C++指针数组内存泄漏

发布于 2024-12-14 02:52:11 字数 975 浏览 1 评论 0原文

在我的类中,我有一个动态分配的指针数组。我的声明:

 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];

编辑2: 我也解决了这个问题,感谢您的辛勤贡献!

In my class I have a dynamically allocated array of pointers. My declaration:

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

So there is an array of pointers, where each pointer points to a simple Elem struct.

The main question is, how should I properly deallocate the array. If I use only:

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

Valgrind reports 1 not-freed block, which is traced to the line where 'array = new Elem* [size];' states.

On the other hand if I add to the previous code:

delete array;

Which I thought is correct, valgrind reports 0 not-freed blocks, which is perfect, BUT it reports

Mismatched free() / delete / delete []

exactly on the line where 'delete array;' is. I tried 'delete []array' too, but that's just "1 not-freed blocks" too then! If somebody could explain me the proper way it would be much appreciated.

EDIT:
So using:

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

is working probably fine. It is working in one of my classes (I have two similar) the other still reports some small leak. I would think it's just a minor bug somewhere, but valgrind still points to the line where

array = new Elem* [size];

stands.

EDIT2:
I solved this as well, thank you for your exhausting contribution!!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

初雪 2024-12-21 02:52:11

您需要:

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;

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

You need:

delete [] array;

Because it's an array.

I just noticed your note that you tried this too - it's the proper thing to do so I don't know why you'd still be getting an error.

Edit: This deserves a more thorough explanation.

When you create a pointer using new, the pointer may be to a single element or an array of elements depending on the syntax you use. But the pointer type is the same in both cases! The compiler relies on you to know what the pointer points to and treat it accordingly.

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

When you delete a pointer, the destructor is called for the object it points to or for each element of the array. But since the pointer type is the same in each case, the compiler relies on you to give it the proper syntax so it knows what to do.

delete single;
delete [] array;

In your case the elements of the array are pointers also, and pointers don't have destructors. That means those pointers won't be deleted and will become memory leaks if you don't delete them first. You were correct to have a loop to delete them individually before the final delete.

烂柯人 2024-12-21 02:52:11

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

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

You should free everything in the array (if dynamically allocated) and then free the array itself.

for (int i = 0; i < size; i++) { // only free inside if dynamically allocated - not if just storing pointers
   delete array[i];
}
delete[] array; // necesarry
别再吹冷风 2024-12-21 02:52:11

删除数组的语法如下:

delete[] array;

用于删除数组元素指向的对象的 for 循环就可以了。数组本身的删除是唯一的问题。您需要两者 for 循环,然后使用 delete[] 来处理数组本身。

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

我怀疑您尝试过使用 for 循环或 delete[],但没有同时使用两者。如果这样做时仍然存在泄漏或错误,那么您需要向我们展示分配作为数组元素的指针的代码。


使用 std::vector<> 而不是数组意味着您可以不再担心这些具体细节并转向更高的抽象级别。

The syntax for deleting an array is like this:

delete[] array;

Your for loop to delete the objects pointed to by the elements of the array is fine. The deletion of the array itself is the only problem. You need both the for loop and then the delete[] to dispose of the array itself.

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

I suspect that you have tried using the for loop, or the delete[], but not both together. And if when you do that you still have leaks or errors, then you would need to show us the code that allocates the pointers that are elements of the array.


Using std::vector<> instead of an array would mean that you could stop worrying about these nitty gritty details and move to higher level of abstraction.

稚气少女 2024-12-21 02:52:11

在这种情况下,您两者都需要

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

每次调用 new 时,都只调用一次 delete

请注意,虽然您需要在此处调用 delete[] array (因为您使用 new[] 分配了它),但 delete[] 运算符确实对数组元素所指向的对象调用析构函数。这是因为 delete[] 运算符对数组中的对象调用析构函数,而数组包含指针但不包含对象。指针本身没有析构函数。

In this case, you need both.

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

You call delete exactly once for each time you called new.

Note that although you need to call delete[] array here (because you allocated it with new[]), the delete[] operator does not call the destructors on the objects pointed to by elements of the array. This is because the delete[] operator calls destructors on objects in the array, and your array contains pointers but not objects. Pointers do not themselves have destructors.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文