Освобождение памяти в куче. Должен ли я и как?

Я пишу CESetup.dll для приложения Windows Mobile. Он должен быть неуправляемым, с которым у меня мало опыта. Поэтому я не уверен, следует ли мне освобождать память, которую я выделяю, и как я это делаю.

Вот функция, которую я написал:

    Uninstall_Init(
    HWND        hwndParent,
    LPCTSTR     pszInstallDir
)
{
    LPTSTR folderPath = new TCHAR[256];
    _stprintf(folderPath, _T("%s\\cache"), pszInstallDir);
    EmptyDirectory(folderPath);
    RemoveDirectory(folderPath);

    _stprintf(folderPath, _T("%s\\mobileadmin.dat"), pszInstallDir);
    DeleteFile(folderPath);

// To continue uninstallation, return codeUNINSTALL_INIT_CONTINUE
// If you want to cancel installation,
// return codeUNINSTALL_INIT_CANCEL
return codeUNINSTALL_INIT_CONTINUE;
}

Насколько я понимаю, folderPath размещен в куче. EmptyDirectory () - моя собственная функция, которая удаляет все содержимое каталога. RemoveDirectory () и DeleteFile () - это системные вызовы.

Мой вопрос: следует ли мне освободить folderPath до выхода из функции? Если нужно, как мне это сделать?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
0
519
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Да, ты должен. Позвонив

 delete[] folderPath;

в конце вашей функции. Вся память, назначенная с помощью new, должна быть освобождена с помощью delete.

Есть распространенное заблуждение, которое я видел у людей, которые не привыкли к программированию на C / C++ - когда они видят функцию с параметром указателя, они думают, что переменная должна быть выделена с помощью новый. Это не так, локальная переменная подходит и предпочтительнее, поскольку вам не нужно беспокоиться о ее времени жизни.

Вы можете значительно упростить себе жизнь, сделав

TCHAR folderPath[256];

Я предпочитаю использовать std :: string, но я выделил это в отдельном ответе.

Ты совершенно прав. Но я попробовал это, и он не компилировался для меня.

ageektrapped 27.10.2008 18:19

Я получаю такие ошибки, как «DeleteFileW: не удается преобразовать параметр 1 из LPTSTR [256] в LPCWSTR»

ageektrapped 27.10.2008 18:20

Ага - вы объявляете массив LPTSTR, а не TCHAR.

Mark Ransom 27.10.2008 18:28

Ах. Намного лучше! Спасибо. C++ \ Win32 - это такая боль.

ageektrapped 27.10.2008 18:32
Ответ принят как подходящий

Я думаю, вы хотите использовать это:

delete [] folderPath;

Похоже, вы выделяете массив TCHAR, что имеет смысл, поскольку это строка. Когда вы выделяете массив, вы должны удалить его с помощью оператора удаления массива (который вы получаете, включив скобки в оператор удаления). Я почти уверен, что с решением Треба вы получите утечку памяти.

Да, вам следует освободить память. Ни одна из вызываемых вами функций не сделает этого за вас, да и не должна - в этом нет никакого смысла. Память была выделена оператором вектора new, поэтому ее следует освободить оператором удаления вектора, то есть:

удалить [] folderPath;

Как правило, лучше использовать std :: string или, в вашем случае, std :: basic_string. В этом случае это исключает возможное переполнение буфера, когда ваш окончательный путь превышает 256 символов.

    Uninstall_Init(
    HWND        hwndParent,
    LPCTSTR     pszInstallDir
)
{
    std::basic_string<TCHAR> folderPath = pszInstallDir;
    folderPath.append(_T("\\cache"));
    EmptyDirectory(folderPath.c_str());
    RemoveDirectory(folderPath.c_str());
    folderPath = pszInstallDir;
    folderPath.append(_T("\\mobileadmin.dat"));
    DeleteFile(folderPath.c_str());
// To continue uninstallation, return codeUNINSTALL_INIT_CONTINUE
// If you want to cancel installation,
// return codeUNINSTALL_INIT_CANCEL
return codeUNINSTALL_INIT_CONTINUE;
}

Это работает на устройствах Windows Mobile? Что я должен включить?

ageektrapped 27.10.2008 18:42

У меня нет прямого опыта работы с Windows Mobile, но это часть C++, а не ОС. Вам нужно #include <string>.

Mark Ransom 27.10.2008 18:45

Другие вопросы по теме