If the pointer is received on a regular array - it is clear, it is necessary to fix, even in the examples there is such a thing on msdn. And if the pointer is received from IntPtr or is IntPtr itself - is it necessary to fix? How to understand when to fix, and when not to?
Allocate unmanaged memory:
internal unsafe class Memory { // Heap API flags private const uint HEAP_ZERO_MEMORY = 0x00000008; // Heap API functions [DllImport("Kernel32")] private static extern IntPtr GetProcessHeap(); [DllImport("Kernel32")] private static extern int HeapSize(IntPtr hHeap, uint dwFlags, IntPtr lpMem); [DllImport("Kernel32")] private static extern IntPtr HeapAlloc(IntPtr hHeap, uint dwFlags, UIntPtr dwBytes); [DllImport("Kernel32")] private static extern IntPtr HeapReAlloc(IntPtr hHeap, uint dwFlags, IntPtr lpMem, UIntPtr dwBytes); [DllImport("Kernel32")] private static extern bool HeapFree(IntPtr hHeap, uint flags, IntPtr lpMem); // Handle for the process heap. This handle is used in all calls to the // HeapXXX APIs in the methods below. private static IntPtr ph = GetProcessHeap(); // Private instance constructor to prevent instantiation. private Memory() { } // Allocates a memory block of the given size. The allocated memory is // automatically initialized to zero. public static IntPtr Alloc(int size) { IntPtr result = HeapAlloc(ph, HEAP_ZERO_MEMORY, new UIntPtr((uint)size)); if (result == null) throw new OutOfMemoryException(); return result; } // Frees a memory block. public static void Free(IntPtr block) { if (!HeapFree(ph, 0, block)) throw new InvalidOperationException(); } // Re-allocates a memory block. If the reallocation request is for a // larger size, the additional region of memory is automatically // initialized to zero. public static IntPtr ReAlloc(IntPtr block, int size) { IntPtr result = HeapReAlloc(ph, HEAP_ZERO_MEMORY, block, new UIntPtr((uint)size)); if (result == null) throw new OutOfMemoryException(); return result; } // Returns the size of a memory block. public static int SizeOf(IntPtr block) { int result = HeapSize(ph, 0, block); if (result == -1) throw new InvalidOperationException(); return result; } } We declare IntPtr as a class field:
class Program { static IntPtr buffer = IntPtr.Zero; static unsafe void Main(string[] args) { buffer = Memory.Alloc(100); byte* ptr = (byte*)buffer.ToPointer(); // Не снесет ли сборщик мусора указатель ptr в произвольном месте? Console.Read(); } }