在我的班级中,我有一个动态分配的指针数组。我的声明:
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 []
正好在'删除数组;'的行上是。我也试过'删除[]数组',但那只是“1个未释放的块”!如果有人能够以正确的方式向我解释,我将不胜感激。
修改 所以使用:
for (int i = 0; i < size; i++) {
delete array[i];
}
delete[] array;
工作得很好。它在我的一个班级(我有两个类似的)工作,另一个仍然报告一些小漏洞。我认为这只是一个小错误,但是valgrind仍指向
行array = new Elem* [size];
表示。
EDIT2: 我也解决了这个问题,谢谢你的贡献!
答案 0 :(得分: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;
在您的情况下,数组的元素也是指针,指针没有析构函数。这意味着这些指针不会被删除,如果你不先删除它们将成为内存泄漏。在最终删除之前,有一个循环可以单独删除它们。
答案 1 :(得分: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
答案 2 :(得分:5)
删除数组的语法如下:
delete[] array;
你的for
循环删除数组元素指向的对象很好。删除数组本身是唯一的问题。您需要 for
循环,然后delete[]
才能处理数组本身。
for (int i = 0; i < size; i++) {
delete array[i];
}
delete[] array;
我怀疑您已尝试使用for
循环或delete[]
,但不是两者都在一起。如果你这样做仍然有泄漏或错误,那么你需要向我们展示分配作为数组元素的指针的代码。
使用std::vector<>
代替数组意味着您可以不再担心这些细节,并转向更高级别的抽象。
答案 3 :(得分:2)
在这种情况下,您需要 both 。
for (int i = 0; i < size; i++) {
delete array[i];
}
delete[] array;
每次拨打delete
时,您都会拨打new
一次。
请注意,虽然您需要在此处致电delete[] array
(因为您使用new[]
分配了它),但delete[]
运算符会不调用析构函数数组元素指向的对象。这是因为delete[]
运算符调用数组中对象上的析构函数,并且数组包含指针但不包含对象。指针本身不具有析构函数。