释放/删除char *会导致无效的堆指针断言失败

时间:2011-07-19 21:29:28

标签: dll interop c++-cli memory-management

我有一大堆代码用于获取CLR DLL中映射驱动器的UNC路径,但是当我在最后释放内存时,char数组导致无效的堆指针断言失败,我假设它与InteropServices分配它有关,但是我想确保它不会变成内存泄漏,因为这个函数被反复调用。

代码:

DWORD MAX_DEVICE_LENGTH = 1000;
TCHAR* szDeviceName = new TCHAR[MAX_DEVICE_LENGTH];
memset(szDeviceName, '\0', MAX_DEVICE_LENGTH); 
DWORD dwResult; 


char* charpath = (char*)   (void*)System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi(path->Substring(0,2));
wchar_t* tpath = new wchar_t[MAX_DEVICE_LENGTH];

memset(tpath, '\0', MAX_DEVICE_LENGTH);

DWORD dwNum = MultiByteToWideChar (CP_ACP, 0, charpath, -1, NULL, 0);
MultiByteToWideChar (CP_ACP, 0, charpath, -1, tpath, dwNum );


dwResult = WNetGetConnection(
    tpath,
    szDeviceName, &MAX_DEVICE_LENGTH); 

System::String ^ str = gcnew System::String(szDeviceName);

str += path->Substring(2, path->Length-2);

delete(szDeviceName);
free(charpath); //This is where it assert-fails
delete(tpath);

return str;

这可能是我不理解的内存解除分配的基本内容,但无论哪种方式值得搞清楚。如果它有帮助,如果我跳过该行tpath删除正常,但如果charpath断言失败,那么tpath也将失败。

4 个答案:

答案 0 :(得分:8)

MSDN的相关评论

  

StringToHGlobalAnsi对于自定义封送或混合时非常有用   托管和非托管代码。因为这个方法分配了   字符串所需的非托管内存,始终释放内存   致电FreeHGlobal。 StringToHGlobalAnsi提供相反的结果   Marshal.PtrToStringAnsi的功能。

所以,除了FreeHGlobal之外没有删除/免费。

答案 1 :(得分:5)

szDeviceNametpath使用delete[]代替delete[]版本适用于数组,非[]版本适用于单个对象。

答案 2 :(得分:1)

根据MSDN,您应该使用FreeHGlobal

释放内存

答案 3 :(得分:1)

这是错的:

free(charpath);

charpath分配StringToHGlobalAnsi后,您应致电FreeHGlobal。像这样:

Marshal::FreeHGlobal(IntPtr(charpath));