Can Memory<T> be created from a pointer?

Can Memory<T> be created with a pointer and a length? If not, how come?
9 Replies
reflectronic
reflectronic2mo ago
you would need to use https://github.com/dotnet/runtime/blob/main/src/libraries/Common/src/System/Memory/PointerMemoryManager.cs (or something that does the same thing) just copy it into your project, and use myMemoryManager.Memory
nathanAjacobs
nathanAjacobs2mo ago
Ty this will work! I was going crazy looking for a something in the BCL that does this.
Servator
Servator2mo ago
AI Answer:
unsafe
{
byte* ptr = stackalloc byte[100];
System.Runtime.InteropServices.MemoryMarshal.CreateFromPinnedArray(new Span<byte>(ptr, 100));
}
unsafe
{
byte* ptr = stackalloc byte[100];
System.Runtime.InteropServices.MemoryMarshal.CreateFromPinnedArray(new Span<byte>(ptr, 100));
}
reflectronic
reflectronic2mo ago
CreateFromPinnedArray takes an array, not a span, so that does not work but, there was an attempt
Servator
Servator2mo ago
GPT-4:
unsafe
{
fixed (int* ptr = array)
{
// Create a Span<int> from pointer and length
Span<int> span = new Span<int>(ptr, length);

// Use the span to initialize memory
for (int i = 0; i < span.Length; i++)
span[i] = i;

// Optionally convert to Memory<int>
Memory<int> memory = MemoryMarshal.CreateFromPinnedArray(array, 0, length);

// Example usage of Memory<int>
foreach (var item in memory.Span)
Console.WriteLine(item);
}
}
unsafe
{
fixed (int* ptr = array)
{
// Create a Span<int> from pointer and length
Span<int> span = new Span<int>(ptr, length);

// Use the span to initialize memory
for (int i = 0; i < span.Length; i++)
span[i] = i;

// Optionally convert to Memory<int>
Memory<int> memory = MemoryMarshal.CreateFromPinnedArray(array, 0, length);

// Example usage of Memory<int>
foreach (var item in memory.Span)
Console.WriteLine(item);
}
}
Still same issue i think damn
nathanAjacobs
nathanAjacobs2mo ago
Yeah I tried asking copilot earlier and got a lot of stuff that was incorrect
Servator
Servator2mo ago
My last attempt:
unsafe
{
var ptr = stackalloc byte[100];
var byteArray = new byte[100];
Marshal.Copy((IntPtr)ptr, byteArray, 0, 100);
var memory = new Memory<byte>(byteArray);
}
unsafe
{
var ptr = stackalloc byte[100];
var byteArray = new byte[100];
Marshal.Copy((IntPtr)ptr, byteArray, 0, 100);
var memory = new Memory<byte>(byteArray);
}
public unsafe Memory<T> CreateMemoryFromPointer<T>(T* ptr, int length) where T : unmanaged
{
int size = sizeof(T);
byte* bytePtr = (byte*)ptr;

byte[] byteArray = new byte[length * size];

fixed (byte* destination = byteArray)
{
System.Buffer.MemoryCopy(bytePtr, destination, length * size, length * size);
}

return new Memory<T>(byteArray, 0, length);
}
public unsafe Memory<T> CreateMemoryFromPointer<T>(T* ptr, int length) where T : unmanaged
{
int size = sizeof(T);
byte* bytePtr = (byte*)ptr;

byte[] byteArray = new byte[length * size];

fixed (byte* destination = byteArray)
{
System.Buffer.MemoryCopy(bytePtr, destination, length * size, length * size);
}

return new Memory<T>(byteArray, 0, length);
}
Looks like you could use something like this. I didn't test it tho.
unsafe
{
int* ptr = stackalloc int[100];
var memory = CreateMemoryFromPointer(ptr, 100);
}
unsafe
{
int* ptr = stackalloc int[100];
var memory = CreateMemoryFromPointer(ptr, 100);
}
then this should work according to ai
nathanAjacobs
nathanAjacobs2mo ago
This allocates a managed array and has to perform a copy. The MemoryManager<T> is the better solution
FusedQyou
FusedQyou2mo ago
Please don't post AI answers, especially because they are often wrong like is the case here