Table of Contents

Struct NativeMemory

Namespace
Sdl3Sharp.Utilities
Assembly
Sdl3Sharp.dll

Represents an allocated native memory buffer of unspecified type. Also provides methods for managing native memory allocations, including managing SDL's internal allocators.

public readonly struct NativeMemory : IEquatable<ReadOnlyNativeMemory>, IEqualityOperators<NativeMemory, ReadOnlyNativeMemory, bool>, IEquatable<NativeMemory>, ISpanFormattable, IFormattable, IEqualityOperators<NativeMemory, NativeMemory, bool>
Implements
Inherited Members

Remarks

Note: Some of the static methods in this class require the caller to manually free the allocated memory using the appropriate free method (e.g., Free(void*) or AlignedFree(void*)). Failure to do so may result in memory leaks.

Properties

AllocationCount

Gets the number of outstanding (unfreed) allocations

public static int AllocationCount { get; }

Property Value

int

The number of outstanding (unfreed) allocations, or -1 if allocation counting is disabled

Empty

Gets an empty NativeMemory

public static NativeMemory Empty { get; }

Property Value

NativeMemory

An empty NativeMemory

IsEmpty

Gets a value indicating whether the allocated memory buffer is empty

public bool IsEmpty { get; }

Property Value

bool

A value indicating whether the allocated memory buffer is empty

See Also

IsPinned

Gets a value indicating whether the underlying NativeMemoryManagerBase of this allocated memory buffer is pinned

[MemberNotNullWhen(true, new string[] { "mMemoryManager", "MemoryManager" })]
public bool IsPinned { get; }

Property Value

bool

A value indicating whether the underlying NativeMemoryManagerBase of this allocated memory buffer is pinned

See Also

IsValid

Gets a value indicating whether the allocated memory buffer is valid

public bool IsValid { get; }

Property Value

bool

A value indicating whether the allocated memory buffer is valid

Remarks

A valid NativeMemory might become invalid after the underlying NativeMemoryManager changed (e.g. by calling TryRealloc(ref NativeMemoryManager?, nuint) on it).

Length

Gets the number of bytes in the allocated memory buffer

public nuint Length { get; }

Property Value

nuint

The number of bytes in the allocated memory buffer

Pointer

Gets a pointer to the start of the allocated memory buffer

public nint Pointer { get; }

Property Value

nint

A pointer to the start of the allocated memory buffer

Methods

AlignedAlloc(nuint, nuint)

Allocates uninitialized memory that is aligned to a specific alignment

public static void* AlignedAlloc(nuint alignment, nuint size)

Parameters

alignment nuint

The alignment of the memory

size nuint

The size in bytes to allocate

Returns

void*

A pointer to the allocated uninitialized aligned memory, or null if the allocation failed

Remarks

The memory returned by this method must be freed with AlignedFree(void*), not Free(void*).

If the alignment is less than sizeof(void*), it will be increased to match that instead.

The returned memory address will be a multiple of the alignment, and the actual size of the memory allocated will be a multiple of the alignment too.

AlignedFree(void*)

Frees memory allocated by AlignedAlloc(nuint, nuint)

public static void AlignedFree(void* memory)

Parameters

memory void*

A pointer previously returned by AlignedAlloc(nuint, nuint), or null

Remarks

The memory is no longer valid after a call to this method and pointers into it should not be dereferenced anymore.

If the memory pointer is null, this method does nothing.

Calloc(nuint, nuint)

Allocates zero-initialized memory to hold a given number of elements of a given size

public static void* Calloc(nuint elementCount, nuint elementSize)

Parameters

elementCount nuint

The number of elements to allocate

elementSize nuint

The size in bytes of each individual element

Returns

void*

A pointer to the allocated zero-initialized memory, or null if the allocation failed

Remarks

The memory returned by this method must be freed with Free(void*).

If either of elementCount or elementSize are 0, they will both be set to 1 instead.

The returned memory is guaranteed to be aligned to either the fundamental alignment (alignof(max_align_t) in C11 and later) or 2 * sizeof(void*), whichever is smaller.

Equals(NativeMemory)

Indicates whether the current object is equal to another object of the same type.

public bool Equals(NativeMemory other)

Parameters

other NativeMemory

An object to compare with this object.

Returns

bool

true if the current object is equal to the other parameter; otherwise, false.

Equals(ReadOnlyNativeMemory)

Indicates whether the current object is equal to another object of the same type.

public bool Equals(ReadOnlyNativeMemory other)

Parameters

other ReadOnlyNativeMemory

An object to compare with this object.

Returns

bool

true if the current object is equal to the other parameter; otherwise, false.

Equals(object?)

Indicates whether this instance and a specified object are equal.

public override bool Equals(object? obj)

Parameters

obj object

The object to compare with the current instance.

Returns

bool

true if obj and this instance are the same type and represent the same value; otherwise, false.

Free(void*)

Frees allocated memory

public static void Free(void* memory)

Parameters

memory void*

A pointer to allocated memory, or null

Remarks

The memory is no longer valid after a call to this method and pointers into it should not be dereferenced anymore.

If the memory pointer is null, this method does nothing.

GetHashCode()

Returns the hash code for this instance.

public override int GetHashCode()

Returns

int

A 32-bit signed integer that is the hash code for this instance.

GetMemoryFunctions()

Gets the current set of SDL's native memory functions

public static INativeMemoryFunctions GetMemoryFunctions()

Returns

INativeMemoryFunctions

The current set of SDL's native memory functions

Remarks

This does not hold a lock, so do not call this in the unlikely event of a background thread calling TrySetMemoryFunctions(INativeMemoryFunctions) simultaneously.

GetOriginalMemoryFunctions()

Gets the original set of SDL's native memory functions

public static INativeMemoryFunctions GetOriginalMemoryFunctions()

Returns

INativeMemoryFunctions

The original set of SDL's native memory functions

Remarks

This is what Malloc(nuint) and friends will use by default, if there has been no change made by a call to TrySetMemoryFunctions(INativeMemoryFunctions). These functions are not necessarily using the C runtime's malloc and friends functions behind the scenes! Different platforms and build configurations might do any number of unexpected things.

Malloc(nuint)

Allocates uninitialized memory

public static void* Malloc(nuint size)

Parameters

size nuint

The size in bytes to allocate

Returns

void*

A pointer to the allocated uninitialized memory, or null if the allocation failed

Remarks

The memory returned by this method must be freed with Free(void*).

If size is 0, it will be set to 1 instead.

The returned memory is guaranteed to be aligned to either the fundamental alignment (alignof(max_align_t) in C11 and later) or 2 * sizeof(void*), whichever is smaller. Use AlignedAlloc(nuint, nuint) if you need to allocate memory aligned to an alignment greater than this guarantee.

MemCmp(void*, void*, nuint)

Compares two buffers of memory

public static int MemCmp(void* firstBuffer, void* secondBuffer, nuint length)

Parameters

firstBuffer void*

The first buffer to compare

secondBuffer void*

The second buffer to compare

length nuint

The number of bytes to compare between the buffers

Returns

int

A value less than 0, if firstBuffer is considered "less than" secondBuffer after the first length bytes; otherwise, a value greater than 0, if firstBuffer is considered "greater than" secondBuffer after the first length bytes; otherwise, 0, which means firstBuffer matches secondBuffer exactly for length bytes

Remarks

There are special checks in place, for when firstBuffer or secondBuffer are null:

  • firstBuffer and secondBuffer are both nullThis method returns 0
  • firstBuffer is null while secondBuffer is notThis method returns -1
  • firstBuffer is not null while secondBuffer isThis method returns 1

Notice that in all of the special cases above the length doesn't play a role.

Note: There are no additional checks in place regarding the length of the buffers and the given length parameter. Make sure that both buffers, firstBuffer and secondBuffer, are safely dereferencable for reading for at least length bytes!

MemCpy(void*, void*, nuint)

Copies specified number of bytes from one buffer of memory into another non-overlapping one

public static void* MemCpy(void* destination, void* source, nuint length)

Parameters

destination void*

The destination memory region. Must not overlap with source.

source void*

The source memory region. Must not overlap with destination.

length nuint

The length in bytes of both destination and source

Returns

void*

The same pointer as the given destination

Remarks

There are special checks in place, for when destination or source are null. In those cases destination is just returned (even if it's null) without doing anything else.

The memory regions must not overlap! If they might do, use MemMove(void*, void*, nuint) instead.

Note: There are no additional checks in place regarding the length of the buffers and the given length parameter. Make sure that destination is safely dereferenable for writing and source is safely dereferencable for reading, both for at least length bytes!

MemMove(void*, void*, nuint)

Copies specified number of bytes form one buffer of memory into another one that might overlap

public static void* MemMove(void* destination, void* source, nuint length)

Parameters

destination void*

The destination memory region

source void*

The source memory region

length nuint

The length in bytes of both destination and source

Returns

void*

The same pointer as the given destination

Remarks

There are special checks in place, for when destination or source are null. In those cases destination is just returned (even if it's null) without doing anything else.

It is okay for the memory regions to overlap. If you are confident that the regions never overlap, you might want to use MemCpy(void*, void*, nuint) instead to improve performance.

Note: There are no additional checks in place regarding the length of the buffers and the given length parameter. Make sure that destination is safely dereferenable for writing and source is safely dereferencable for reading, both for at least length bytes!

MemSet(void*, byte, nuint)

Initializes all bytes of a buffer of memory to a specified value

public static void* MemSet(void* destination, byte value, nuint length)

Parameters

destination void*

The destination memory region

value byte

The byte value to set

length nuint

The length in bytes to set in destination

Returns

void*

The same pointer as the given destination

Remarks

There is a special check in place, for when destination is null. In that case null is just returned without doing anything else.

Note: There are no additional checks in place regarding the length of destination and the given length parameter. Make sure that destination is safely dereferenable for writing for at least length bytes!

MemSet(void*, uint, nuint)

Initializes all 32-bit words of a buffer of memory to a specific value

public static void* MemSet(void* destination, uint value, nuint dwords)

Parameters

destination void*

The destination memory region

value uint

The uint value to set

dwords nuint

The number of uint values (32-bit words) to set in destination

Returns

void*

The same pointer as the given destination

Remarks

There is a special check in place, for when destination is null. In that case null is just returned without doing anything else.

Note: There are no additional checks in place regarding the length of destination and the given dwords parameter. Make sure that destination is safely dereferenable for writing for at least the number of uint values given by dwords (that is sizeof(uint) * dwords bytes)!

Pin()

Pins the underlying NativeMemoryManager

public NativeMemoryPin Pin()

Returns

NativeMemoryPin

A pin pinning the underlying NativeMemoryManager

Realloc(void*, nuint)

Changes the size of allocated memory

public static void* Realloc(void* memory, nuint newSize)

Parameters

memory void*

A pointer to allocated memory to reallocate, or null

newSize nuint

The new size in bytes of the memory

Returns

void*

A pointer to the newly allocated memory, or null if the allocation failed

Remarks

The memory returned by this method must be freed with Free(void*).

If newSize is 0, it will be set to 1 instead. Note that this is unlike some other C runtime realloc implementations, which may treat Realloc(memory, 0) the same way as Free(memory).

If the memory pointer is null, the behavior of this method is equivalent to Malloc(newSize). Otherwise, the result of this method can have one of three possible outcomes:

  • If it returns the same pointer as memory, it means that the memory was resized in place without freeing
  • If it returns a different non-null pointer, it means that the original memory was freed and cannot be dereferenced there anymore
  • If it returns null (indicating failure), then the memory will remain valid and must still be freed with Free(void*)

The returned memory is guaranteed to be aligned to either the fundamental alignment (alignof(max_align_t) in C11 and later) or 2 * sizeof(void*), whichever is smaller.

ToString()

Returns the fully qualified type name of this instance.

public override string ToString()

Returns

string

The fully qualified type name.

ToString(IFormatProvider?)

Formats the value of the current instance using the specified format.

public string ToString(IFormatProvider? formatProvider)

Parameters

formatProvider IFormatProvider

The provider to use to format the value.

-or-

A null reference (Nothing in Visual Basic) to obtain the numeric format information from the current locale setting of the operating system.

Returns

string

The value of the current instance in the specified format.

ToString(string?)

Formats the value of the current instance using the specified format.

public string ToString(string? format)

Parameters

format string

The format to use.

-or-

A null reference (Nothing in Visual Basic) to use the default format defined for the type of the IFormattable implementation.

Returns

string

The value of the current instance in the specified format.

ToString(string?, IFormatProvider?)

Formats the value of the current instance using the specified format.

public string ToString(string? format, IFormatProvider? formatProvider)

Parameters

format string

The format to use.

-or-

A null reference (Nothing in Visual Basic) to use the default format defined for the type of the IFormattable implementation.

formatProvider IFormatProvider

The provider to use to format the value.

-or-

A null reference (Nothing in Visual Basic) to obtain the numeric format information from the current locale setting of the operating system.

Returns

string

The value of the current instance in the specified format.

TryAlignedAlloc(nuint, nuint, out NativeMemoryManager?)

Tries to allocate uninitialized memory that is aligned to a specific alignment

public static bool TryAlignedAlloc(nuint alignment, nuint length, out NativeMemoryManager? memoryManager)

Parameters

alignment nuint

The alignment of the memory

length nuint

The size in bytes to allocate

memoryManager NativeMemoryManager

The resulting NativeMemoryManager that manages the allocated uninitialized aligned memory, when this method returns true; otherwise, null

Returns

bool

true, if the uninitialized aligned memory could be successfull allocated; otherwise, false

Remarks

The resulting NativeMemoryManager should be disposed when the memory it's managing is no longer needed. That also frees the allocated memory.

If the alignment is less than sizeof(void*), it will be increased to match that instead.

The value of the resulting NativeMemoryManager's Pointer property will be a multiple of the alignment, and the actual size of the memory allocated (not necessarily identical to Length) will be a multiple of the alignment too.

TryCalloc(nuint, nuint, out NativeMemoryManager?)

Tries to allocate zero-initialized memory to hold a given number of elements of a given size

public static bool TryCalloc(nuint elementCount, nuint elementSize, out NativeMemoryManager? memoryManager)

Parameters

elementCount nuint

The number of elements to allocate

elementSize nuint

The size in bytes of each individual element

memoryManager NativeMemoryManager

The resulting NativeMemoryManager that manages the allocated zero-initialized memory, when this method returns true; otherwise, null

Returns

bool

true, if the zero-initialized memory could be successfull allocated; otherwise, false

Remarks

The resulting NativeMemoryManager should be disposed when the memory it's managing is no longer needed. That also frees the allocated memory.

If either of elementCount or elementSize are 0, they will both be set to 1 instead.

The value of the resulting NativeMemoryManager's Pointer property is guaranteed to be aligned to either the fundamental alignment (alignof(max_align_t) in C11 and later) or 2 * sizeof(void*), whichever is smaller.

TryCompare(ReadOnlyNativeMemory, ReadOnlyNativeMemory, out int)

Tries to compare two allocated memory buffers

public static bool TryCompare(ReadOnlyNativeMemory firstBuffer, ReadOnlyNativeMemory secondBuffer, out int result)

Parameters

firstBuffer ReadOnlyNativeMemory

The first buffer to compare

secondBuffer ReadOnlyNativeMemory

The second buffer to compare

result int

default(int), when this method returns false; otherwise, a value less than 0, if firstBuffer is considered "less than" secondBuffer; otherwise, a value greater than 0, if firstBuffer is considered "greater than" secondBuffer; otherwise, 0, which means firstBuffer matches secondBuffer exactly

Returns

bool

true, if firstBuffer and secondBuffer are both valid and have the same Length; otherwise, false

Remarks

If one of firstBuffer or secondBuffer is empty (or both are), this method returns true and result is 0.

TryCopy(NativeMemory, ReadOnlyNativeMemory)

Tries to copy all bytes from one allocated memory buffer into another non-overlapping one

public static bool TryCopy(NativeMemory destination, ReadOnlyNativeMemory source)

Parameters

destination NativeMemory

The destination memory buffer. Must not overlap with source.

source ReadOnlyNativeMemory

The source memory buffer. Must not overlap with destination.

Returns

bool

true, if destination and source are both valid and destination's Length is at least source's Length; otherwise, false

Remarks

The memory regions must not overlap! If they might do, use TryMove(NativeMemory, ReadOnlyNativeMemory) instead.

TryFormat(Span<char>, out int, ReadOnlySpan<char>, IFormatProvider?)

Tries to format the value of the current instance into the provided span of characters.

public bool TryFormat(Span<char> destination, out int charsWritten, ReadOnlySpan<char> format = default, IFormatProvider? provider = null)

Parameters

destination Span<char>

The span in which to write this instance's value formatted as a span of characters.

charsWritten int

When this method returns, contains the number of characters that were written in destination.

format ReadOnlySpan<char>

A span containing the characters that represent a standard or custom format string that defines the acceptable format for destination.

provider IFormatProvider

An optional object that supplies culture-specific formatting information for destination.

Returns

bool

true if the formatting was successful; otherwise, false.

TryMalloc(nuint, out NativeMemoryManager?)

Tries to allocate uninitialized memory

public static bool TryMalloc(nuint length, out NativeMemoryManager? memoryManager)

Parameters

length nuint

The size in bytes to allocate

memoryManager NativeMemoryManager

The resulting NativeMemoryManager that manages the allocated uninitialized memory, when this method returns true; otherwise, null

Returns

bool

true, if the uninitialized memory could be successfull allocated; otherwise, false

Remarks

The resulting NativeMemoryManager should be disposed when the memory it's managing is no longer needed. That also frees the allocated memory.

If length is 0, it will be set to 1 instead.

The value of the resulting NativeMemoryManager's Pointer property is guaranteed to be aligned to either the fundamental alignment (alignof(max_align_t) in C11 and later) or 2 * sizeof(void*), whichever is smaller. Use TryAlignedAlloc(nuint, nuint, out NativeMemoryManager?) if you need to allocate memory aligned to an alignment greater than this guarantee.

TryMove(NativeMemory, ReadOnlyNativeMemory)

Tries to copy all bytes from one allocated memory buffer into another one that might overlap

public static bool TryMove(NativeMemory destination, ReadOnlyNativeMemory source)

Parameters

destination NativeMemory

The destination memory buffer

source ReadOnlyNativeMemory

The source memory buffer

Returns

bool

true, if destination and source are both valid and destination's Length is at least source's Length; otherwise, false

Remarks

It is okay for the memory regions to overlap. If you are confident that the regions never overlap, you might want to use TryCopy(NativeMemory, ReadOnlyNativeMemory) instead to improve performance.

TryRealloc(ref NativeMemoryManager?, nuint)

Tries to change the size of allocated native memory that is managed by a NativeMemoryManager

public static bool TryRealloc(ref NativeMemoryManager? memoryManager, nuint newLength)

Parameters

memoryManager NativeMemoryManager

A reference to NativeMemoryManager that manages the native memory to reallocate, or a reference to null. If this reference is referencing a null value, it might be referencing an actual NativeMemoryManager when this method returns true.

newLength nuint

The new size in bytes of the memory

Returns

bool

true, if the memory could be successfull reallocated; otherwise, false

Remarks

The resulting NativeMemoryManager should be still disposed when the memory it's managing is no longer needed. That also frees the allocated memory.

The referenced NativeMemoryManager cannot be NativeMemoryManager.IsPinned. Trying to reallocated a pinned memory buffer results in failure.

If newLength is 0, it will be set to 1 instead. Note that this is unlike some other C runtime realloc implementations, which may treat TryRealloc(ref memoryManager, 0) the same way as memoryManager.Dispose().

If the reference to memoryManager is referencing a null value, the behavior of this method is equivalent to TryMalloc(newLength, out memoryManager). Otherwise, a call to this method can have one of three possible outcomes:

  • If the result of the call to this method is true and the values of memoryManager's Pointer, before and after this operation, are the same, it means that the original memory was resized in place without freeing
  • If the result of the call to this method is true and the values of memoryManager's Pointer, before and after this operation, are different, it means that the original memory was freed and all active references to it (e.g. lasting Span<T>s) are invalid and cannot be dereferenced anymore (NativeMemory and NativeMemory<T> instances are safe though)
  • The result of the call to this method is false (indicating failure), then the given memoryManager will remain valid (if it was non-null) and should be still disposed when it's no longer needed

The value of the resulting NativeMemoryManager's Pointer property is guaranteed to be aligned to either the fundamental alignment (alignof(max_align_t) in C11 and later) or 2 * sizeof(void*), whichever is smaller.

TrySet(NativeMemory, byte)

Tries to initialize all bytes of an allocated memory buffer to a specified value

public static bool TrySet(NativeMemory destination, byte value)

Parameters

destination NativeMemory

The allocated memory buffer

value byte

The byte value to set

Returns

bool

true, if destination is valid; otherwise, false

TrySet(NativeMemory, uint)

Tries to initialize all 32-bit words of an allocated memory buffer to a specific value

public static bool TrySet(NativeMemory destination, uint value)

Parameters

destination NativeMemory

The allocated memory buffer

value uint

The uint value to set

Returns

bool

true, if destination is valid; otherwise, false

TrySetMemoryFunctions(INativeMemoryFunctions)

Tries to replace SDL's native memory functions with a custom set

public static bool TrySetMemoryFunctions(INativeMemoryFunctions memoryFunctions)

Parameters

memoryFunctions INativeMemoryFunctions

The set of custom native memory functions to replace SDL's current one

Returns

bool

true, if the set of SDL's current native memory functions was successfully replaced by the given custom one; otherwise, false (check TryGet(out string?) for more information)

Remarks

It is not safe to call this method once any allocations have been made, as future calls to Free(void*) will use the new allocator, even if those allocations were allocated by an older set of native memory functions!

If this method is used, usually it needs to be the very first call made using the SDL library, if not the very first thing to do at the program's startup time.

Operators

operator ==(NativeMemory, NativeMemory)

Compares two values to determine equality.

public static bool operator ==(NativeMemory left, NativeMemory right)

Parameters

left NativeMemory

The value to compare with right.

right NativeMemory

The value to compare with left.

Returns

bool

true if left is equal to right; otherwise, false.

operator ==(NativeMemory, ReadOnlyNativeMemory)

Compares two values to determine equality.

public static bool operator ==(NativeMemory left, ReadOnlyNativeMemory right)

Parameters

left NativeMemory

The value to compare with right.

right ReadOnlyNativeMemory

The value to compare with left.

Returns

bool

true if left is equal to right; otherwise, false.

implicit operator ReadOnlyNativeMemory(NativeMemory)

public static implicit operator ReadOnlyNativeMemory(NativeMemory nativeMemory)

Parameters

nativeMemory NativeMemory

The allocated memory buffer of unspecified type to convert to an allocated read-only memory buffer of unspecified type

Returns

ReadOnlyNativeMemory

An allocated read-only memory buffer of unspecified type spanning the exact same memory region as the given nativeMemory

operator !=(NativeMemory, NativeMemory)

Compares two values to determine inequality.

public static bool operator !=(NativeMemory left, NativeMemory right)

Parameters

left NativeMemory

The value to compare with right.

right NativeMemory

The value to compare with left.

Returns

bool

true if left is not equal to right; otherwise, false.

operator !=(NativeMemory, ReadOnlyNativeMemory)

Compares two values to determine inequality.

public static bool operator !=(NativeMemory left, ReadOnlyNativeMemory right)

Parameters

left NativeMemory

The value to compare with right.

right ReadOnlyNativeMemory

The value to compare with left.

Returns

bool

true if left is not equal to right; otherwise, false.