Arrays, Spans, and Memory

Separate ownership, algorithms, and borrowed contiguous views before translating C# array code.

Core.BaseOwned + borrowedPorting guide

Owned sequences, algorithms, and views

Sharp Runtime maps most C# one-dimensional array work to an owned std::vector<T>, familiar System::Array algorithms, and explicit borrowed views. Those pieces are intentionally separate: an algorithm class should not pretend to own a vector, and a view should not pretend to retain its owner.

Selection guide

If you need…Use…Remember…
Owned resizable contiguous elementsstd::vector<T>Growth can relocate storage
Familiar sort/copy/search/clear helpersSystem::ArrayStatic algorithms over vectors/raw buffers
Synchronous writable borrowSpan<T>Owner must outlive it
Synchronous read-only borrowReadOnlySpan<T>Read-only through this alias only
Offset/count vector viewArraySegment<T>Default segment and mutation have edge cases
Managed-style Memory nameMemory<T>Still non-owning in this implementation
Collection interfaces/versioned enumerationList-shaped collectionElement ownership remains a C++ choice

Key differences from C#

  • There is no universal CLR System.Array base object or runtime covariance.
  • Native vector[] is unchecked; Span and runtime helpers add explicit checks.
  • A vector can resize, so views and references can become invalid.
  • Copying follows the exact C++ element type, including smart-pointer or move-only semantics.
  • Current Memory and ArraySegment types borrow their vector instead of retaining managed storage.
  • Rectangular multidimensional arrays need a deliberate nested, flat, matrix, or domain representation.

Core component

Array, Span, Memory, and ArraySegment are public entries in Core.Base. Select it directly for a narrow consumer:

set(SHARP_RUNTIME_COMPONENTS Core.Base)
set(SHARP_RUNTIME_BUILD_TESTS OFF CACHE BOOL "" FORCE)
add_subdirectory(sharp-runtime)
target_link_libraries(app PRIVATE SharpRuntime::Core.Base)

Detailed documentation

Safety invariant

A view is never the owner

Do not retain Span, Memory, ArraySegment, iterators, references, or raw pointers after owner destruction or vector relocation. Current Memory::Pin exposes a pointer; it does not retain or immobilize native storage.