Делает станд.:: vector.clear () действительно удаляют (свободная память) на каждом элементе?

Рассмотрите этот код:

#include <vector>

void Example()
{
    std::vector<TCHAR*> list;
    TCHAR* pLine = new TCHAR[20];
    list.push_back(pLine);
    list.clear();    // is delete called here?
    // is delete pLine; necessary?
}

Делает list.clear() звонить delete на каждом элементе? Т.е. сделайте я должен освободить память прежде / после list.clear()?

59
задан squareskittles 23 September 2019 в 13:57
поделиться

0 ответов

Нет (необходимо сделать удаление себя в конце, как Вы предполагаете в своем примере, поскольку разрушение лысого указателя ничего не делает). Но можно использовать повышение [или другая основанная на RAII идиома] интеллектуальный указатель для создания этого Делай как надо (auto_ptr не работал бы правильно в контейнере, поскольку это имеет несовместимое поведение при копировании и т.д.), но быть уверенным, что Вы понимаете ловушки таких интеллектуальных указателей перед использованием. (Как Benoit упоминает, в этом случае, basic_string то, что Вы действительно ищете здесь.)

сказавший, что существует потребность понять ловушки интеллектуальных указателей, имея их, заботятся об управлении памятью неявно, таким образом, Вы не должны делать этого, явно намного менее подвержено ошибкам.

РЕДАКТИРОВАНИЕ: Существенно пересмотренный для затрагивания элементов Benoit, приведенный в его намного более полный ответ, благодаря сильному подталкиванию от Earwicker и James Matta - благодарит продвинуть меня делать должную осмотрительность на этом!

35
ответ дан Ruben Bartelink 24 November 2019 в 18:23
поделиться

станд.:: вектор действительно называет деструктор каждого элемента, который он содержит, когда ясный () назван. В Вашем особом случае это уничтожает указатель, но объекты остаются.

Интеллектуальные указатели являются правильным способом пойти, но быть осторожными. auto_ptr не может использоваться в контейнерах станд. повышение:: scoped_ptr не может также. повышение:: shared_ptr может, но он не будет работать в Вашем случае, потому что у Вас нет указателя на объект, Вы на самом деле используете массив. Таким образом, решение Вашей проблемы состоит в том, чтобы использовать повышение:: shared_array.

, Но я предлагаю, чтобы Вы использовали станд.:: basic_string вместо этого, где Вы не должны будете иметь дело с управлением памятью, все еще извлекая пользу из работы со строкой.

50
ответ дан squareskittles 24 November 2019 в 18:23
поделиться

Вот один способ, которым можно сказать, что он не делает - пробуют его на классе, это не полностью определяется:

#include <vector>
class NotDefined;

void clearVector( std::vector<NotDefined*>& clearme )
{
    clearme.clear();    // is delete called here?
}

, Если этот отрывок компилирует, то он не может называть деструктор, потому что деструктор не определяется.

8
ответ дан tfinniga 24 November 2019 в 18:23
поделиться

Нет. Это не делает этого, так как нет никакой гарантии, Вы не используете указатель больше нигде. Если бы это не была переменная указателя, то это освободило бы их (путем вызова деструктора)

5
ответ дан Mehrdad Afshari 24 November 2019 в 18:23
поделиться

Вы могли бы также быть в состоянии использовать Библиотека Контейнера Указателя Повышения . Не конкретно рекомендуемый здесь (снова, потому что Вы используете массивы вместо отдельных объектов, хотя std::string заботился бы о том), но это - полезная и малоизвестная библиотека, которая решает проблему, указанную в заголовке.

0
ответ дан Head Geek 24 November 2019 в 18:23
поделиться
Другие вопросы по тегам:

Похожие вопросы: