【C++/CLI】托管转非托管时产生的char*及char**的内存释放

场景

C++/CLI主要用于对c++编译的dll进行封装,方便.net调用。既然说到C++,难免dll中会有多处使用到指针,比较常见的就是外部传入一个List,需要在CLI中转化成char**,然后才能调用对应的c++方法。作为中间变量,这些被我们临时生成的指针需要手动释放。简单场景代码如下:

    array<String^>^ list;//500个字符串
    int count = list->Length;
    char** arrays = new char*[count];
    for (int i = 0; i < count; i++)
    {
    	arrays[i] = (char*)(void*)Marshal::StringToHGlobalAnsi(list[i]);
    }
    
    // use arrays in C++ function
    
    //free memory
    for (int i = 0; i < count; i++)
    {
    	delete arrays[i];
    }
    delete[] arrays;

基本上c++的指针释放都是这么操作。但是在C++/CLI中就出现了错误,释放内存时出现溢出。
尝试过只使用delete[] arrays。能正常运行,但是内存没有被正确释放。

解决方案

  1. char* ptr = (char*)(void*)Marshal::StringToHGlobalAnsi(string),这是托管字符串转非托管char指针的操作。对应的内存释放操作是Marshal::FreeHGlobal(IntPtr(ptr))
  2. 这个场景下的二维数组char**内存释放应该由两部分组成。释放成员指针,再释放数组指针。
 for (int i = 0; i < count; i++)
 {
     Marshal::FreeHGlobal(IntPtr(arrays[i]));
 }
 delete[] arrays;
  1. 经10万次循环测试,没有出现内存溢出。而原方法在循环几百次后,内存已经泄露了100MB以上。

相关参考:

  1. https://m.imooc.com/article/30475
  2. https://stackoverflow.com/questions/6754415/free-delete-a-char-causes-an-invalid-heap-pointer-assertion-failure
  3. https://docs.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.marshal.stringtohglobalansi?redirectedfrom=MSDN&view=netcore-3.1#System_Runtime_InteropServices_Marshal_StringToHGlobalAnsi_System_String_

你可能感兴趣的:(C#/.NET,C++,错误处理,C++/CLI)