在C#中,如何删除由c分配的指针?

时间:2014-09-24 13:36:53

标签: c# pinvoke

#define EXPORT_DLL extern "C" __declspec(dllexport) 

EXPORT_DLL int* alloc(int size)
{
    int* result = new int[size];
    return result;
}

在c#中,使用P / Inovke调用此函数:

public class Model
{
    [DllImport("Win32Project1.dll", EntryPoint = "alloc", CallingConvention = CallingConvention.Cdecl)]
    extern static IntPtr Alloc(int size);

    public int[] Data { get; set; }

    public Model(int size)
    {
        IntPtr ptr = Alloc(size);
        Data = new int[size];
        Marshal.Copy(ptr, Data, 0, Data.Length);
    }
}

然后,创建一个类似的测试:

class Program
{
    static void Main(string[] args)
    {

        List<Model> list = new List<Model>();

        list.Add(new Model(10240000));
        list.Add(new Model(10240000));
        list.Add(new Model(10240000));
        list.Add(new Model(10240000));
        list.Add(new Model(10240000));
        list.Clear();
        GC.Collect();

    }
}

但是,当GC.Collect()执行时,只收集了托管内存。那么有没有办法释放由c函数分配的内存?

1 个答案:

答案 0 :(得分:3)

您正在创建的C API需要公开.NET代码可以调用的释放函数。

有很多方法可以在C / C ++中分配内存(例如newmallocGlobalAlloc,...),以便单个Marshall.Delete工作。因此,将匹配的释放添加到要从.NET调用的本机代码中。

(在.NET方面,最好看一下专门的SafeHandle来自动调用该释放函数。)