Search code examples
c#intptr

dynamic way to free intPtr


I have large class which in many places I need to convert array to intPtr

IntPtr convertToIntPtr(Array input)
{
    if (input != null)
    {
        int s = Marshal.SizeOf(input.GetValue(0).GetType()) * input.Length;
        System.IntPtr p = Marshal.AllocHGlobal(s);

        return p;
    }
    return new IntPtr();
}

I know each pointer can be freed using Marshal.FreeHGlobal(IntPtr).

my question is : - will garbagecollector free intptr once used - If no how can I free all of them in close or dispose of class , any event to use such that when intpntr no far used to be deleted


Solution

  • No, the memory you allocate is non-GC handled memory, so it won't be freed (technically it will be freed when your program ends... But I don't think it's what you want).

    What you can do is incapsulate the IntPtr in a disposable object.

    public sealed class ArrayToIntPtr : IDisposable
    {
        public IntPtr Ptr { get; protected set; }
    
        public ArrayToIntPtr(Array input)
        {
            if (input != null)
            {
                int s = Marshal.SizeOf(input.GetValue(0).GetType()) * input.Length;
                Ptr = Marshal.AllocHGlobal(s);
            }
            else
            {
                Ptr = IntPtr.Zero;
            }
        }
    
        ~ArrayToIntPtr()
        {
            Dispose(false);
        }
    
        public void Dispose()
        {
            Dispose(true);
        }
    
        protected void Dispose(bool disposing)
        {
            if (Ptr != IntPtr.Zero)
            {
                Marshal.FreeHGlobal(Ptr);
                Ptr = IntPtr.Zero;
            }
    
            if (disposing)
            {
                GC.SuppressFinalize(this);
            }
        }
    }
    

    (note that the class is sealed, so the Dispose(bool disposing) isn't virtual)