Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Free/delete a char* causes an invalid heap pointer assertion failure

I have a chunk of code that I'm using to get the UNC path of a mapped drive in a CLR DLL, but when I'm freeing memory at the end, a char array causes an invalid heap pointer assertion failure, and I'm assuming it has to do with it being allocated by InteropServices, but I want to make sure it doesn't turn into a memory leak as this function gets called repeatedly.

Code:

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;

It's probably something basic about memory de-allocation that I don't understand, but either way it's worth figuring out. If it helps, if I skip over that line tpath deletes fine, but if the charpath assertion fails then tpath will fail as well.

like image 662
Itskiddly Avatar asked Jul 19 '11 21:07

Itskiddly


2 Answers

The relevant comment on MSDN is

StringToHGlobalAnsi is useful for custom marshaling or when mixing managed and unmanaged code. Because this method allocates the unmanaged memory required for a string, always free the memory by calling FreeHGlobal. StringToHGlobalAnsi provides the opposite functionality of Marshal.PtrToStringAnsi.

So, no delete/free but FreeHGlobal.

like image 186
Andrei Avatar answered Dec 14 '22 22:12

Andrei


For szDeviceName and tpath use delete[] instead of delete. [] version is for arrays and non-[] version is for single objects.

like image 29
Andrey Agibalov Avatar answered Dec 15 '22 00:12

Andrey Agibalov