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



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

代码:

DWORD MAX_DEVICE_LENGTH = 1000;
TCHAR* szDeviceName = new TCHAR[MAX_DEVICE_LENGTH];
memset(szDeviceName, '', 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, '', 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也会失败。

MSDN上的相关注释为

StringToHGlobalAnsi对于自定义封送或混合时很有用托管和非托管代码。因为这个方法分配字符串所需的非托管内存,总是通过调用FreeHGlobal。StringToHGlobalAnsi提供了相反的功能Marshal.PtrToStringAnsi.

所以,没有删除/free,只有FreeHGlobal

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

根据MSDN,您应该使用FreeHGlobal

释放内存。

这是不对的:

free(charpath);

由于charpath是由StringToHGlobalAnsi分配的,所以应该调用FreeHGlobal。这样的:

Marshal::FreeHGlobal(IntPtr(charpath));

最新更新