c ++ valgrind удаление двойного указателя для предотвращения утечки памяти

После прочтения:
C ++ Массив указателей: удалить или удалить []?
(ответ от Шаи Васида)
а также
http://www.cplusplus.com/forum/beginner/6651/

Я реализовал следующее:

kernel.h

unsigned int **ConfigMeM;
//.....
~Kernel(){ //destructor
for (unsigned int i=0; i<MeMSize; i++)
delete [] MeM[i]; //Valgrind:- Invalid read of size 4
- Invalid free() / delete / delete[] / realloc()
delete [] MeM; //Valgrind: Invalid free() / delete / delete[] / realloc()

for (unsigned int i=0; i<_item_tot; i++)
delete [] ConfigMeM[i]; //Valgrind: Same comments as above
delete [] ConfigMeM; //Valgrind: same as above
};

Kernel.cpp

//.......
MeM = new unsigned int*[MeMSize];
for (unsigned int i=0; i<MeMSize; i++){
MeM[i] = new unsigned int[11]; //Valgrind: 14,608 bytes in 332 blocks are definitely lost in loss record 2,021 of 2,036
}
for (unsigned int i=0; i<MeMSize; i++){
for (int j=0; j<10; j++){
MeM[i][j] = 0;
}
}
//.....
ConfigMeM = new unsigned int*[_item_tot];
for (unsigned int i=0; i<_item_tot; i++){
ConfigMeM[i] = new unsigned int[3]; //Valgrind: 1,200 bytes in 100 blocks are definitely lost in loss record 1,131 of 2,036
}
for (unsigned int i=0; i<_item_tot; i++){
for (int j=0; j<3; j++){
ConfigMeM[i][j] = 0;
}
}
//.....

Я не уверен, что я делаю неправильно.

Любые предложения, пожалуйста?

Спасибо.

0

Решение

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

Самое простое решение — предотвратить копирование, удалив эти функции:

Kernel(Kernel const&) = delete;
void operator=(Kernel const &) = delete;

или, если вы застряли с древним компилятором, объявите их закрытыми без тела функции.

Если вам нужно скопировать эти объекты, вам нужно будет реализовать их, возможно, для выполнения «глубокого копирования», которое выделяет новые блоки памяти.

Кроме того, это может быть проще в использовании std::vector управлять своими динамическими массивами; это уже имеет правильную семантику копирования и может быть инициализировано довольно просто:

std::vector<std::vector<unsigned int>> MeM, ConfigMem;

(MemSize, std::vector<unsigned int>(11));
1

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

Других решений пока нет …

По вопросам рекламы [email protected]