Как правильно освободить вектор C ++?

Возможный дубликат:
Как правильно освободить или удалить вектор C ++?

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

Итак, у меня есть такой код в шаблонном классе под названием Set

template <class T>
class Set {
public:
// stuff
private:
int size;
std::vector<T> list;
};

А в конструкторе я выделил память для вектора. Поэтому я называю list = new std :: vector;

Для вашего интереса, вот мой конструктор копирования и оператор присваивания, которые я также видел, где я также выделяю память для вектора:

template <class T>
Set<T>::Set(const Set& aSet)
{
size = aSet.size;
list->clear();
list = new vector<T>;
for (int i = 0; i < size; ++i) {
list[i] = aSet.list[i];
}
}

template <class T>
Set<T>& Set<T>::operator=(const Set& right)
{
if (this != &right) {
list->clear();
size = right.size;
list = new vector<T>;
for (int i = 0; i < size; ++i) {
list[i] = right.list[i];
}
}
return (*this);
}

В деструкторе у меня просто есть list.clear (), чтобы удалить все элементы и затем освободить память.

Но проблема в том, что когда я запускаю valgrind для моего файла .out, он говорит мне, что я определенно потерял часть памяти, и я не знаю, почему он говорит мне об этом. Я прочитал некоторые вопросы здесь, на Stackoverflow, но я в основном все перепробовал. Я попытался очистить (), а затем удалить на вектор, но это не сработало. Затем я попытался стереть (list.begin (), list.end ()), но это тоже не сработало.

Мой мыслительный процесс заключается в том, что я использую Set * aSet = new Set; в моем основном классе, и так как int не является объектом, он не освобождается, когда я вызываю list.clear (). Это правильно? Как мне правильно удалить память?

Спасибо за любую помощь.

Edit1 = измененный список * для setList

Мои новые конструкторы и оператор присваивания:

template <class T>
Set<T>::Set(const Set& aSet)
{
size = aSet.size;
setList.clear();
setList = aSet.setList;
}

template <class T>
Set<T>& Set<T>::operator=(const Set& right)
{
if (this != &right) {
setList.clear();
size = right.size;
setList = right.setList;
}
return (*this);
}

Valgrind все еще сообщает, что у меня такое же количество потерянной памяти. В моем деструкторе у меня все еще есть list.clear ()

Журнал Valgrind:

==11398==
==11398== HEAP SUMMARY:
==11398==     in use at exit: 62,969 bytes in 352 blocks
==11398==   total heap usage: 540 allocs, 188 frees, 68,046 bytes allocated
==11398==
==11398== LEAK SUMMARY:
==11398==    definitely lost: 8,624 bytes in 14 blocks
==11398==    indirectly lost: 1,168 bytes in 5 blocks
==11398==      possibly lost: 4,829 bytes in 56 blocks
==11398==    still reachable: 48,348 bytes in 277 blocks
==11398==         suppressed: 0 bytes in 0 blocks
==11398== Rerun with --leak-check=full to see details of leaked memory

0

Решение

Мой мыслительный процесс заключается в том, что я использую Set *aSet = new Set; в моем основном классе, и так как int не является объектом, он не освобождается, когда я вызываю list.clear (). Это правильно? Как мне правильно удалить память?

Нет. Чтобы удалить память, которую вы правильно распределите, вам нужно вызвать delete:

Set *aSet = new Set;

delete aSet;

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

Set aSet;
// no delete required. Variable destroyed/deallocated when it goes out of scope.

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

std::unique_ptr<Set> aSet(new aSet);

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

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


std::vector<T>::clear() не требуется для освобождения памяти вектора. Вы можете использовать функцию-член C ++ 11 shrink_to_fit(), или вы можете использовать трюк подкачки:

std::vector<int> list;

...

std::vector<int>(list).swap(list);

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

4

Другие решения

Прежде чем сделать new list тебе нужно сделать delete listиначе вы получите утечку памяти, как вы обнаружили. Там нет необходимости clear список, прежде чем удалить его, деструктор автоматически очистит его. Редактировать: Вам также нужно удалить указатель в Set класс деструктор.

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

Более тематический совет — использовать std::vector как прямая переменная-член вместо указателя. В этом случае вам обязательно нужно использовать clear,

2

Если вы работаете в C ++ 11, вы можете использовать Уменьшать до размеров(). Из того, что я понимаю, хотя это не является обязательным, и реализация может помешать его сокращению.

1
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector