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.
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
.
For szDeviceName
and tpath
use delete[]
instead of delete
. []
version is for arrays and non-[]
version is for single objects.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With