Освободить / удалить символ * приводит к ошибке подтверждения неверного указателя кучи - PullRequest
5 голосов
/ 20 июля 2011

У меня есть кусок кода, который я использую, чтобы получить UNC-путь подключенного диска в DLL-библиотеке CLR, но когда я освобождаю память в конце, массив 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 ]

8 голосов
/ 20 июля 2011

Соответствующий комментарий к MSDN :

StringToHGlobalAnsi полезен для пользовательского маршалинга или при смешивании управляемого и неуправляемого кода.Поскольку этот метод выделяет неуправляемую память, необходимую для строки, всегда освобождайте память, вызывая FreeHGlobal.StringToHGlobalAnsi обеспечивает противоположную функциональность Marshal.PtrToStringAnsi.

Таким образом, удаление / удаление не требуется, но FreeHGlobal.

5 голосов
/ 20 июля 2011

Для szDeviceName и tpath используйте delete[] вместо delete.[] версия предназначена для массивов, а не [] версия предназначена для отдельных объектов.

1 голос
/ 20 июля 2011

Это просто неправильно:

free(charpath);

Поскольку charpath был выделен StringToHGlobalAnsi, вам следует позвонить FreeHGlobal. Как это:

Marshal::FreeHGlobal(IntPtr(charpath));
1 голос
/ 20 июля 2011

Согласно MSDN , вы должны освободить память с помощью FreeHGlobal

...