我有一大堆代码用于获取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也将失败。
答案 0 :(得分:8)
MSDN的相关评论
StringToHGlobalAnsi对于自定义封送或混合时非常有用 托管和非托管代码。因为这个方法分配了 字符串所需的非托管内存,始终释放内存 致电FreeHGlobal。 StringToHGlobalAnsi提供相反的结果 Marshal.PtrToStringAnsi的功能。
所以,除了FreeHGlobal
之外没有删除/免费。
答案 1 :(得分:5)
szDeviceName
和tpath
使用delete[]
代替delete
。 []
版本适用于数组,非[]
版本适用于单个对象。
答案 2 :(得分:1)
根据MSDN,您应该使用FreeHGlobal
答案 3 :(得分:1)
这是错的:
free(charpath);
由charpath
分配StringToHGlobalAnsi
后,您应致电FreeHGlobal
。像这样:
Marshal::FreeHGlobal(IntPtr(charpath));