Еще один вопрос утечки векторной памяти в C ++ - PullRequest
3 голосов
/ 01 сентября 2010

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

В функции рисования я сначала создаю новый вектор с теми же указателями, а затем начинаю с цикла for, который зацикливает количество сущностей, которые я хочу нарисовать. Внутри этого цикла есть еще один цикл, который определяет, какой объект должен быть нарисован, и когда объект рисуется, его указатель удаляется из вектора с помощью vector.erase (), поэтому один и тот же объект не будет нарисован дважды (вот почему я создаю копию вектора, содержащего указатели объектов).

Как бы то ни было, сам мой код работает, и объекты рисуются так, как я хочу, но у меня возникает утечка памяти (я действительно вижу, что объем памяти в диспетчере задач Windows увеличивается на 28 Кбит / с).

Утечка памяти сохраняется, даже если я закомментирую все, кроме этого:

vector<Entity*> list = ent_list; // ent_list is the list of entity pointers
list.clear();

Так что я предполагаю, что что-то упустил, но я не уверен, что. Я полагал, что, поскольку я не использовал «новое», память позаботилась бы, но, очевидно, это не так ... Надеюсь, кто-то может мне помочь!

/ Феодор

Ответы [ 4 ]

4 голосов
/ 01 сентября 2010

Ссылка на vector :: clear говорит: «если элементы вектора являются указателями на объекты, эта функция не будет вызывать соответствующие деструкторы».Вы уверены, что не полагаетесь на это?

1 голос
/ 01 сентября 2010

Вектор не удалит память за вашими указателями. Вам придется удалить каждую сущность * перед вызовом clear (), или вы можете использовать «умный контейнер» в качестве boost :: ptr_vector .

1 голос
/ 01 сентября 2010

Нет, стандартные контейнеры стирают только созданную ими память; std::list.clear(); только делает недействительными и удаляет сами итераторы, а не выделенную вами память.

Вы должны вызывать std::list.remove() или std::list.erase() каждый итератор за другим и вручную удалять указатели, которые вы сами выделили.

0 голосов
/ 01 сентября 2010

Самый простой способ исправить это - заменить элемент контейнера на boost::shared_ptr<Element>. Это, вероятно, очистит код, который также использует вектор, и обеспечит указатель на лучшую практику управления памятью в дальнейшем.

...