Is it ok to use a reference return of the converted pointer's value?
I have read this question. How is return by reference implemented in C#?
Is it ok to use the code below about garbage collector's memory move problem. (Helper.GetReference() & Helper.GetPointer())
class Program
{
static unsafe void Main(string[] args)
{
byte[] bytes = new byte[1024];
ref SomeStruct reference = ref Helper.GetReference<SomeStruct>(bytes);
reference.field1 = 1;
reference.field2 = 2;
SomeStruct* pointer = Helper.GetPointer<SomeStruct>(bytes);
pointer->field1 = 3;
pointer->field2 = 4;
}
}
public static class Helper
{
// Can I use this?
public static unsafe ref T GetReference<T>(byte[] bytes) where T : unmanaged
{
fixed (byte* p1 = bytes)
{
T* p2 = (T*)p1;
return ref *p2;
}
}
// Shouldn't I use it?
public static unsafe T* GetPointer<T>(byte[] bytes) where T : unmanaged
{
fixed (byte* p1 = bytes)
{
return (T*)p1;
}
}
}
public struct SomeStruct
{
public int field1;
public int field2;
}
As far i know, both of these methods are unsafe... Yes it does compile, however, because you have used unsafe
in your Helper
methods and referenced the same memory, your safety-net has been blown.
You are pointing to a portion of memory (a managed object) that can be moved by the Garbage Collector (aka your array), potentially leaving you with a dangling-pointer
You would need to fix (fixed
) the array in your Main
method to ensure safety (they way i see it), or your struct
Eg
fixed (byte* p = bytes) // even though p isn't being used
{
SomeStruct* pointer = Helper.GetPointer<SomeStruct>(bytes);
pointer->field1 = 3;
pointer->field2 = 4;
}