Many people do not know this (and why you have so many answers that you cannot), but for .NET there is something that can be done for such things: SafeHandle .
In fact, the .NET 2.0 page for one of its derived classes has an example using AllocHGlobal . When the SafeUnmanagedMemoryHandle finalizer is SafeUnmanagedMemoryHandle , it automatically calls FreeHGlobal for you. (If you want deterministic cleanup instead of just waiting for the finalizer to finish, you need to either explicitly call Close() or Dispose() ).
It just requires a few code changes on your part:
internal static SafeUnmanagedMemoryHandle StructToPtr(object obj) { var ptr = Marshal.AllocHGlobal(Marshal.SizeOf(obj)); Marshal.StructureToPtr(obj, ptr, false); return new SafeUnmanagedMemoryHandle(ptr, true); } [DllImport("SDL2.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_RenderCopy")] internal static extern int RenderCopy(IntPtr renderer, IntPtr texture, SafeUnmanagedMemoryHandle srcrect, SafeUnmanagedMemoryHandle dstrect);
Once you do this, your original Copy example will work exactly as you expected.
public int Copy(Texture texture, Rect srcrect, Rect dstrect) { return SDL.RenderCopy(_ptr, texture._ptr, Util.StructToPtr(srcrect), Util.StructToPtr(dstrect)); }
When two pointers go out of scope and exit, they will be cleared after that. I don't know how _ptr used, or if Texture is a class that you control, but they can also be switched to SafeHandle .
UPDATE:. If you want to learn more about how to handle unmanaged resources (and get an example of a better IDisposable implementation template better than the example provided by MSDN) I highly recommend the article " IDisposable: What Your Mother Never Told You About Releasing Resources " by Stephen Cleary . He has an in-depth understanding of how to write his own SafeHandles in an article.
application
Here is a copy of the example if the link is ever dead:
using System; using System.Security.Permissions; using System.Runtime.InteropServices; using Microsoft.Win32.SafeHandles; namespace SafeHandleExamples { class Example { public static void Main() { IntPtr ptr = Marshal.AllocHGlobal(10); Console.WriteLine("Ten bytes of unmanaged memory allocated."); SafeUnmanagedMemoryHandle memHandle = new SafeUnmanagedMemoryHandle(ptr, true); if (memHandle.IsInvalid) { Console.WriteLine("SafeUnmanagedMemoryHandle is invalid!."); } else { Console.WriteLine("SafeUnmanagedMemoryHandle class initialized to unmanaged memory."); } Console.ReadLine(); } }