c++数组指针内存泄漏

C++ array of pointer memory leaks

本文关键字:泄漏 内存 指针 数组 c++      更新时间:2023-10-16

在我的类中我有一个动态分配的指针数组。我的宣言:

 array = new Elem* [size];
 for (int i = 0; i < size; i++) {
    array[i] = NULL;
 }

有一个指针数组,其中每个指针都指向一个简单的Elem结构体。

主要的问题是,我应该如何正确地释放数组。如果我只使用:

for (int i = 0; i < size; i++) {
   delete array[i];
}

Valgrind报告1个未释放的块,跟踪到'array = new Elem* [size];'所在的行。

另一方面,如果我加上前面的代码:

delete array;

我认为是正确的,valgrind报告0个未释放的块,这是完美的,但是它报告

Mismatched free() / delete / delete []

正好在'delete array;'所在的行上。我也试过"delete []array",但那只是"1个未释放的块"!如果有人能给我解释一下正确的方法,我将不胜感激。

编辑:

所以使用:

for (int i = 0; i < size; i++) {
   delete array[i];
}
delete[] array;

可能工作正常。它在我的一个类(我有两个类似的)中工作,另一个仍然报告一些小泄漏。我认为这只是一个小错误,但valgrind仍然指向

所在的行
array = new Elem* [size];

EDIT2: 我也解决了这个问题,谢谢你的辛苦贡献!!

您需要:

delete [] array;

因为它是一个数组

我刚刚注意到你的笔记,你也试过这个-这是正确的事情,所以我不知道为什么你仍然得到一个错误。

编辑:这需要一个更彻底的解释。

当您使用new创建指针时,该指针可以指向单个元素或元素数组,这取决于您使用的语法。但是在这两种情况下,指针类型是相同的!编译器依赖于你知道指针指向什么,并相应地处理它。

Elem ** single = new Elem*;    // pointer to one pointer
single[0] = new Elem;          // OK
single[1] = new Elem;          // runtime error, but not compile time
Elem ** array = new Elem* [2]; // pointer to array of pointers
array[0] = new Elem;           // OK
array[1] = new Elem;           // OK

删除指针时,将为其指向的对象或数组的每个元素调用析构函数。但是,由于每种情况下的指针类型都是相同的,编译器依赖于您为其提供正确的语法,以便它知道该怎么做。

delete single;
delete [] array;

在你的例子中,数组的元素也是指针,而指针没有析构函数。这意味着这些指针不会被删除,如果不先删除它们,就会造成内存泄漏。在最后一次删除之前,使用一个循环分别删除它们是正确的。

您应该释放数组中的所有内容(如果是动态分配的),然后释放数组本身。

for (int i = 0; i < size; i++) { // only free inside if dynamically allocated - not if just storing pointers
   delete array[i];
}
delete[] array; // necesarry

删除数组的语法如下:

delete[] array;

您的for循环删除数组元素所指向的对象是可以的。数组本身的删除是唯一的问题。您需要 for循环和delete[]来处理数组本身。

for (int i = 0; i < size; i++) {
   delete array[i];
}
delete[] array;

我怀疑你已经尝试过使用for循环,或delete[],但不是同时使用。如果你这样做,仍然有泄漏或错误,那么你需要向我们展示分配指针的代码,这些指针是数组的元素。


使用std::vector<>而不是数组将意味着您可以停止担心这些琐碎的细节,并移动到更高的抽象级别。

在这种情况下,您需要

for (int i = 0; i < size; i++) {
   delete array[i];
}
delete[] array;

每次调用new,正好调用一次delete

注意,尽管这里需要调用delete[] array(因为您为它分配了new[]),但delete[]操作符调用数组元素所指向对象的析构函数。这是因为delete[]操作符对数组中的对象调用析构函数,并且数组中包含指针但不包含对象。指针本身没有析构函数