If I allocate some memory with AllocHGlobal, do I have to free it with FreeHGlobal?

.net, c#, interop, memory

Solution

Yes, C# will not automatically free memory allocated by `Marshal.AllocHGlobal`. That memory must be freed with a call to `Marshal.FreeHGlobal` or else it will be leaked.

You could create something a smart pointer to wrap the `IntPtr`

class StructWrapper : IDisposable {
    public IntPtr Ptr { get; private set; }

    public StructWrapper(object obj) {
         if (Ptr != null) {
             Ptr = Marshal.AllocHGlobal(Marshal.SizeOf(obj));
             Marshal.StructureToPtr(obj, Ptr, false);
         }
         else {
             Ptr = IntPtr.Zero;
         }
    }

    ~StructWrapper() {
        if (Ptr != IntPtr.Zero) {
            Marshal.FreeHGlobal(Ptr);
            Ptr = IntPtr.Zero;
        }
    }

    public void Dispose() {
       Marshal.FreeHGlobal(Ptr);
       Ptr = IntPtr.Zero;
       GC.SuppressFinalize(this);
    }

    public static implicit operator IntPtr(StructWrapper w) {
        return w.Ptr;
    }
}

Using this wrapper you can either manually free the memory by wrapping the object in a `using` statement or by allowing it to be freed when the finalizer runs.

Problem

I wrote a helper method, ``` internal static IntPtr StructToPtr(object obj) { var ptr = Marshal.AllocHGlobal(Marshal.SizeOf(obj)); Marshal.StructureToPtr(obj, ptr, false); return ptr; } ``` Which takes a `struct` and gives me back an `IntPtr` to it. I use it as such: ``` public int Copy(Texture texture, Rect srcrect, Rect dstrect) { return SDL.RenderCopy(_ptr, texture._ptr, Util.StructToPtr(srcrect), Util.StructToPtr(dstrect)); } ``` The problem is that I only need that `IntPtr` for a split second so that I can pass it off to the C DLL, ``` [DllImport("SDL2.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_RenderCopy")] internal static extern int RenderCopy(IntPtr renderer, IntPtr texture, IntPtr srcrect, IntPtr dstrect); ``` I don't really want to have to worry about freeing it; otherwise my 1-line function grows to 6: ``` public int Copy(Texture texture, Rect? srcrect=null, Rect? dstrect=null) { var srcptr = Util.StructToPtr(srcrect); var dstptr = Util.StructToPtr(dstrect); var result = SDL.RenderCopy(_ptr, texture._ptr, srcptr, dstptr); Marshal.FreeHGlobal(srcptr); Marshal.FreeHGlobal(dstptr); return result; } ``` Is there a better way to do this? Will C# eventually clean up any memory it has allocated? If not, is there a way I can wrap the call to `SDL.RenderCopy` in some `using` statements instead so that I don't have to do all this temporary variable + explicit freeing non-sense?

Original source