2011-11-03 76 views
2

在我的类中,我有一个动态分配的指针数组。我的声明:指针内存泄漏的C++数组

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未释放的块,其被追踪到线,其中“阵列=新ELEM * [大小];”状态。

在另一方面,如果我加入到以前的代码:

delete array; 

而且我认为他是正确的,Valgrind的报告0未释放的块,这是完美的,但它报告

Mismatched free()/delete/delete [] 

恰好在'删除数组'的行上。是。我也尝试过'删除[]数组',但那也只是“1个未被释放的块”!如果有人能以正确的方式向我解释,我们将非常感激。

编辑: 因此,使用:

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

工作可能罚款。它在我的一个班级工作(我有两个类似的),另一个班级还在报告一些小漏洞。我认为这只是一个小错误的地方,但仍然Valgrind的指向所在行

array = new Elem* [size]; 

看台。

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

+2

它说不释放块得到allocateD? –

+0

让您的生活更轻松:删除所有上述内容,并使用Boost [ptr_vector](http://www.boost.org/doc/libs/1_47_0/libs/ptr_container/doc/ptr_vector.html)。 –

+0

我知道这并不回答你的问题,但是有没有一些理由你不能使用std :: vector 来大大简化内存管理? – Void

回答

7

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

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

你的意思是他应该删除数组中指针指向的所有对象,然后使用'delete []'删除数组中的对象(它们是指针)和数组本身。 –

+1

@DavidSchwartz,说数组中的对象被删除并不准确,而是被销毁。指针没有析构函数,所以在这一步中没有任何反应。 –

+0

@MarkRansom指针具有析构函数。 C++有它们,所以模板可以与内置类型一起工作。 – Pubby

8

您需要:

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; 

在你的情况下,数组的元素也是指针,并且指针没有析构函数。这意味着这些指针不会被删除,并且如果不先删除它们,将会变成内存泄漏。在最终删除之前,您有一个循环单独删除它们是正确的。

+0

OP确实需要'delete []',但我不会将其称为数组。 – cnicutar

+1

@cnicutar,如果它不是数组,那么你会怎么称呼它? 'new []'语法分配一个数组。 –

+0

我会把它称为指向某物的指针。 – cnicutar

5

用于删除数组的语法是这样的:

delete[] array; 

for循环到删除对象通过的阵列是细的元素指向。删除阵列本身是唯一的问题。你需要for循环,然后delete[]来处置数组本身。

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

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


使用std::vector<>而不是数组将意味着你可以不再担心这些细节问题的详细信息,并移动到抽象的更高的水平。

+0

@David好的,我编辑它。信号如何在所有噪声中得到很多,这真是太神奇了。 –

2

在这种情况下,您需要均为

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

你叫delete正是每一次你打电话new时间。

注意,虽然你需要在这里调用delete[] array(因为你new[]分配而言),delete[]符不调用对象析构函数由数组的元素指向。这是因为delete[]运算符调用数组中的对象的析构函数,并且数组包含指针而不包含对象。指针本身不具有析构函数。

+0

我认为在形式上,指针类型有微不足道的析构函数,它什么都不做。 –