Правильно ли я удаляю этот указатель? - PullRequest
0 голосов
/ 17 февраля 2011

У меня есть следующий код:

LPWSTR pszDSPath = NULL;
pszDSPath = new WCHAR[  wcslen(pwszFilter)+
                        wcslen(wstrServer.c_str())+
                        wcslen(var.bstrVal) +
                        1
                     ];

// ....
// ....

if(pszDSPath)
{
    delete pszDSPath; 
    pszDSPath = NULL;
}

Может ли приведенный выше код вызвать утечку памяти?Я не уверен, правильно ли я удаляю pszDSPath или нет.

Ответы [ 3 ]

2 голосов
/ 17 февраля 2011

Вы не используете правильный delete.Существует две формы new: скаляр new, который создает отдельный объект (например, new int), и массив new, который создает массив (например, new int[42]).

АналогичноЕсть две формы delete: delete и delete[].Если вы используете new, вы должны использовать delete, чтобы уничтожить объект, а если вы используете new[], вы должны использовать delete[], чтобы уничтожить объект.

Поскольку вы использовали new[] для создания объекта, на который указывает pszDSPath, вы должны использовать delete[] pszDSPath для уничтожения объекта.

Обратите внимание, что это будет сделаногораздо проще, если вы только что использовали std::vector:

std::size_t n = wcslen(pwszFilter)+
                wcslen(wstrServer.c_str())+
                wcslen(var.bstrVal) +
                1;

std::vector<WCHAR> v(n);

// &v[0] can be used as you are using pszDSPath in your current code.

В C ++ вам следует отказаться от ручного управления памятью: это чрезвычайно трудно сделать правильно и требует много работы.В стандартной библиотеке C ++ есть библиотечные средства, в том числе контейнеры, такие как std::vector и std::map, и интеллектуальные указатели, такие как std::auto_ptr, std::unique_ptr и std::shared_ptr, которые управляют временем жизни объектов.Вы не должны выполнять больше работы, чем должны: если вы думаете, что вам нужно написать delete где-то в вашем коде, ваш код, вероятно, неверен.

Этот принцип использования контейнеров для управления временем жизни ресурса основанв шаблоне проектирования, называемом Scope-Bound Resource Management (SBRM) или Получение ресурсов является инициализацией (RAII) .

(std::unique_ptr является частью C ++ 0x, предназначенной для замены std::auto_ptr, и ваш компилятор может еще не поддерживать его. std::shared_ptr также является частью C ++ 0x, но он был доступен около десяти лет в составе библиотек Boost (как boost::shared_ptr) и был включенв C ++ TR1.)

1 голос
/ 17 февраля 2011

Используйте delete[] pszDSPath, чтобы избежать утечек памяти при предварительном выделении массива.

0 голосов
/ 17 февраля 2011

Используйте delete[], чтобы избежать неопределенного поведения.

Однако использование delete в вашем случае почти никогда не вызовет утечку памяти в одиночку - либо она будет работать, либополучить что-то намного хуже, чем утечка памяти.Не рискуйте - используйте delete[].

...