Уничтожение содержимого вектора в C ++ - PullRequest
1 голос
/ 18 февраля 2011

У меня есть std::vector из Element*. Когда деструктор будет вызван. Как это отличается, если это вектор Element

std::vector<Element*> vect;
..

struct Element
{
    Record *elm;        

    Element(Record *rec)
    {
        elm = new Record();
        //...copy from rec
    }
    ~Element()
    {
        delete elm;
    }
};

Я использую вектор следующим образом:

Element *copyElm = new Element(record);
vect.push_back(copyElm);

В приведенном выше коде, как я могу убедиться, что нет утечки.

Ответы [ 5 ]

3 голосов
/ 18 февраля 2011

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

std::vector<boost::shared_ptr<Element> > vect;

Эти классы переносят operator -> и т. Д., Поэтому вы можете использовать их в большинстветак же, как вы использовали обычный указатель.

http://www.boost.org/doc/libs/1_45_0/libs/smart_ptr/shared_ptr.htm

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

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

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

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

В векторе Element* он никогда не вызывается, если только вы сами не позвоните delete.

Посмотрите наУвеличьте shared_ptr для более разумного решения или unique_ptr, если у вас есть компилятор с относительно новыми функциями.

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

vector вызовет освобождение памяти объекта, который он держит (то есть указатели), но не освободит память объекта, который указывает на . Вам нужно освободить память об объекте Element самостоятельно. Если это был vector<Element>, то всякий раз, когда вы делаете push_back, копия элемента вставляется в вектор. vector гарантирует, что освободит память, выделенную для этого скопированного объекта . Но имейте в виду, что с текущим определением Element вы получите ошибку сегмента, так как вы не определили ctor и оператор присваивания.

EDIT Если по какой-то причине вы не хотите использовать умные указатели, тогда единственный вариант - написать функцию release, которая проходит через весь вектор и вызывает delete для сохраненного указателя.

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

Уничтожение указателя всегда запрещено, и есть несколько веских причин, по которым .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...