Search code examples
c#pointersgarbage-collectionunsafe

C# memory after fixed and the Garbage Collector


I am reading bytes from a binary file with BinaryReader.Read and using the fixed statement to 'convert' the bytes into a struct:

[StructLayout(LayoutKind.Sequential, Pack = 1)]
unsafe struct MyStruct
{
    // some variables.. too many to list
    public fixed Byte Software[32];
    public UInt16 FC_Day;
    public UInt16 FC_Year;
    public UInt16 Header_Size; 
    public UInt32 Offset_to_Data;
    // more variables.. too many to list
};

Then later in Main:

byte[] ReadBytes = new byte[227];
MyStruct* Header;
InFile.Read(ReadBytes, 0, 227);
fixed (byte* bHdrPtr = &ReadBytes[0])
{
    Header = (LASHeader*)bHdrPtr;
    //now Header and ReadBytes occupy the same memory
}

At this point any changes to ReadBytes changes Header and visa versa. As I understand it the fixed statement exempts the pointer from moving whilst in the fixed block, but will the structure and bytes now permanently occupy the same memory or will internal memory management move/shuffle the addresses separately? i.e. Can I trust the structure after the fixed block to point to the same meaningful memory and not become random bytes or all 0's?

Previously I was declaring both the bytes[227] and the MyStruct and using Buffer.BlockCopy to copy the bytes from the array to the structure.. this is horribly inefficient requiring double the memory and a block copy each time new bytes are read so I would prefer to recast the bytes like I have done in C++ to save memory and hopefully speed up the process.


Solution

  • but will the structure and bytes now permanently occupy the same memory

    The docs for fixed state:

    After the code in the statement is executed, any pinned variables are unpinned and subject to garbage collection. Therefore, do not point to those variables outside the fixed statement. The variables declared in the fixed statement are scoped to that statement

    As such, no - the change is not permanent - it is scoped only to within the fixed statement.