Search code examples
c#garbage-collectionfixed

Unclear behaviour of a fixed pointer outside of the fixed statement


Can someone explain me why the below C# code doesn't crash? Why does Visual Studio actually allow to compile it? My understanding is that I am getting a fixed pointer, but it is fixed only within the 'fixed' statement. When the pointer is returned from the 'Foo' function, the array 'ar' may be collected. I then force GC to actually do this, but consecutive writing to the memory (which is now deallocated) doesn't cause any error.

class Program
{
    static unsafe byte* Foo()
    {
        byte[] ar = new byte[100];
        fixed (byte* ptr = ar)
        {
            return ptr;
        }
    }

    static unsafe void Main(string[] args)
    {
        byte* ptr = Foo();
        GC.Collect();
        for (int t = 0;;++t) ptr[t%100] = 0;
    }
}

Solution

  • Eric is right, but the answer you probably want to hear is that "sometimes it's useful to retain the address outside of the fixed statement".

    Maybe the memory from that pointer is already fixed by another fixed statement somewhere else, and it makes sense to return it? The compiler is not trying to second guess you and give noisy warnings.

    That said, I'd hope that CodeAnalysis or other advanced tools would step in here where the compiler is letting you cut off your own foot.