Утечки деструктора C ++ с динамической памятью

// Class
ArrayIntVector : IntVector{
private:
  int *data;
  int dataCapacity;
  int numElements;
  void check_invariants() const;
}

// Constructor
ArrayIntVector::ArrayIntVector(int initCapacity)
    : dataCapacity(initCapacity), numElements(0) {
    data = new int[dataCapacity];
    check_invariants();
}

// Destructor
ArrayIntVector::~ArrayIntVector() {
    check_invariants();

    delete[] data;
    data = 0;
}

int main(){

    IntVector *v = new ArrayIntVector(5);
    // testing class functions
    // push_back, pop_back, empty, index, grow
    delete v;
    return 0;
}

У меня утечки. Когда я использую valgrind, я получаю следующее:

СВОДКА КУЧИ: используется на выходе: 20 байтов в 1 блоке, общее использование кучи: 7 выделенных блоков, 7 освобождений, выделено 1284 байта

20 байтов в 1 блоке определенно теряются в записи потери 1 из 1 по адресу 0x4A07152: operator new [] (unsigned long) (vg_replace_malloc.c: 363) по 0x400DBE: ArrayIntVector :: ArrayIntVector (int) (IntVector.cpp: 12) по 0x401142: основной (lab09.cpp: 8)


person user2961535    schedule 14.11.2013    source источник
comment
Пожалуйста, предоставьте полный минимальный рабочий пример, воспроизводящий проблему. В противном случае невозможно определить, в чем проблема, поскольку мы можем только догадываться о том, что вы делаете в коде, который не показывали.   -  person    schedule 15.11.2013
comment
Вам не нужно устанавливать data в значение null после удаления в деструкторе. Когда деструктор выполняется, data больше не существует.   -  person masoud    schedule 15.11.2013
comment
Выдает ли ваш код какое-либо исключение в части // do stuff?   -  person    schedule 15.11.2013
comment
Вы создаете указатель типа IntVector и назначаете ему ArrayIntVector. Предполагая, что это подкласс, помечен ли деструктор как виртуальный?   -  person Jerry Jeremiah    schedule 15.11.2013
comment
Мне сказали установить указатели на null, чтобы вы не могли случайно получить доступ к месту, из которого вы только что удалили вещи. Исключений не возникает. Деструкторы базового и производного классов помечаются как виртуальные в файле заголовка.   -  person user2961535    schedule 15.11.2013
comment
Но кто может получить доступ к data после уничтожения объекта?   -  person juanchopanza    schedule 15.11.2013
comment
Исключена возможность невиртуального деструктора и, учитывая, что у вас есть 7 аллоков и 7 освобождений, возможно, строка data = 0 сбивает с толку valgrind? Это очень маловероятно, но если вы не разместите больше кода, трудно сказать, в чем проблема.   -  person sbabbi    schedule 15.11.2013


Ответы (1)


Проблема в том, что ваш деструктор не виртуальный. Объявите деструктор виртуальным.

person Vlad from Moscow    schedule 14.11.2013
comment
Он объявлен как виртуальный в заголовочном файле - person user2961535; 15.11.2013
comment
@ user2961535: Вы объявили деструктор IntVector виртуальным? - person masoud; 15.11.2013
comment
Деструктор базового класса IntVector объявлен как виртуальный? - person Vlad from Moscow; 15.11.2013
comment
Да, все деструкторы объявлены виртуальными в заголовочном файле - person user2961535; 15.11.2013
comment
В ФАЙЛЕ ЗАГОЛОВКИ // Деструктор для IntVector (базовый класс) virtual ~ IntVector () {}; // Деструктор для ArrayIntVector (производный класс) virtual ~ ArrayIntVector (); все другие используемые функции объявлены в файле заголовка, включая конструктор для производного класса. - person user2961535; 15.11.2013
comment
Check_invariants виртуальный? И что он делает? - person Vlad from Moscow; 15.11.2013
comment
нет, это частная статическая функция-член ArrayIntVector. Он проверяет, что данные не являются пустым указателем, numElements находится между 0 и dataCapacity, включительно, и что dataCapacity имеет значение ›= 0 - person user2961535; 15.11.2013
comment
@ user2961535 Как может статическая функция-член без параметров проверить data? data тоже статичен? - person juanchopanza; 15.11.2013