A C# pointer refers to a memory location. If garbage collection moves an array during heap compaction, a pointer to its former location is no longer suitable for accessing it. A fixed block keeps the array at the same physical memory location until the block ends. section 10.3.4
For pointer-based array copying, declare pointers to both the source and target arrays in fixed, then copy their elements inside the block. The surrounding unsafe block permits pointer use; fixed addresses the separate problem of keeping those arrays from moving. section 10.3.4
Listing 10.10 C# copy array using pointers instead of references
int[] CopyArray(int[] source)
{
int length = source.Length;
int[] target = new int[length]; #1
unsafe #2
{
fixed (int* pSource = source, #3
int* pTarget = target)
{
for (int i = 0; i < length; i++)
{
pTarget[i] = pSource[i]; #4
}
}
}
return target; #5
}
The copy loop reads through pSource and writes through pTarget while both arrays are fixed. section 10.3.4
