delete[]和内存泄漏

3

我想了解C++中的delete[]运算符(我正在使用Visual Studio 2005)。

我有一个未托管的DLL,被托管的DLL调用。当我在调试时执行几个任务后关闭此程序时,我会得到许多(数千个?)内存泄漏,大小大多为24字节-44字节。我怀疑这可能是由于我拥有的某个未托管的DLL引起的。

无论如何,从我所了解的情况来看,如果我有以下代码:

char* pointer = new char[500]
/* some operations... */
delete[] pointer;

那么它的所有内存都将正确释放,我是对的吗?

当我有以下代码时会发生什么:

char* pointer = new char[500];
char* pointerIt = pointer;
/* some code perhaps to iterate over the whole memory block, like so */
for (int i = 0; i < 250; i++){ // only iterate halfway
    *pointerIt = 0;
    pointerIt++;
}

delete[] pointer;

指针所指向的内存已经被删除了,这意味着指针现在不再指向有效的内存。但是没关系,因为我可以将两个指针都设置为NULL,对吗?

无论如何,如果我这样做会发生什么:

char* pointerFirstPosition = new char[500];
char* pointerIt = pointerFirstPosition;

for (int i = 0; i < 250; i++){ // only iterate halfway
    *pointerIt = 0;
    pointerIt++;
}

delete[] pointerIt; // delete the pointer iterator...

这段代码会删除由pointerIt指向的内存块,范围是从pointerIt到pointerIt+500吗?还是会删除由pointerFirstPos指向的内存块,范围是从pointerFirstPos到pointerFirstPos+500呢?

这可能导致内存泄漏吗?

抱歉我的留言有点冗长,我想要清楚地表达我的意思。

谢谢,

kreb


1
“但没关系,因为我可以将两个指针都设置为NULL,对吧?”好的,你应该已经处理完指针了... - GManNickG
2个回答

4

第一组问题:

char* pointer = new char[500] 
/* some operations... */ 
delete[] pointer;

Then all the memory for it is freed up correctly, am I right?

right.

Second question set:

char* pointer = new char[500];
char* pointerIt = pointer;
/* some code perhaps to iterate over the whole memory block, like so */
for (int i = 0; i < 250; i++){ // only iterate halfway
    *pointerIt = 0;
    pointerIt++;
}

delete[] pointer;

The memory pointed to by pointer is deleted right? So it means that pointerIt is now not pointing to valid memory.. But that's ok because I can set both pointers to NULL, right?

指针所指向的内存已经完全被删除了。无论是 pointer 还是 pointerIt,它们都指向无效的内存地址。每个指针只是一个变量,每个变量都是独立的。因此,它们各自存储其自己的地址,互不干扰。解引用运算符 * 将简单地给出该地址处的变量。该地址处的变量是与指针变量不同的变量。

第三组问题:

您应该仅删除已分配的地址,整个数组。如果尝试删除部分数组,则会产生未定义的结果。这可能导致内存泄漏吗?可能会,会导致崩溃吗?可能会,还会导致……?可能会。

因此,只删除您分配的内容。如果您分配了一个数组,则使用 delete[] 删除,如果要删除的类型不是数组,则使用 delete 删除。

以下是一个示例,仅供澄清:

char* pointer = new char[500];
char* pointerIt = pointer;
//This is fine because you are deleting the same address:
delete[] pointerIt;
//The memory that both variables point to is freed, do not try to free again

2
使用newnew[]创建的内容之外的任何东西都不能使用deletedelete[]删除。 - GManNickG
谢谢,这正是我所怀疑的。但是,例如在第三个问题集中,如果我将pointerIt设置为pointerFirstPosition,然后delete[] pointerIt,这仍然是未定义的吗?我正在使用别人的旧代码,他已经离开了公司,我正在尝试弄清楚这是否是内存泄漏的原因。 - krebstar
仅供娱乐,我在g++ 4.4.1下测试了这个代码 - 基本上与您第三个代码示例中的代码相同,只是将pointerIt移动到数组的中间。在pointerIt上调用delete[]会使pointer无效,但是如果行为未定义,则不能期望每个编译器都具有此行为。 - Meredith L. Patterson
@krebstar:我认为我在第三部分已经讲到了。 - Brian R. Bondy
@Meredith 哇,谢谢 :) 我还不知道如何使用Valgrind,而且我现在没有Linux开发机器.. :) 谢谢! - krebstar
显示剩余3条评论

0

1
如果我这样做,我将不得不修改很多项目... :( 这是我的经理无法证明的事情。 - krebstar
对于未来的代码,使用std::vector及其相关函数。永远不要手动分配内存。 - GManNickG
@George: 注意代码需要shared_array。 (或者确实,std::vector。) - sbi
@krebstar 这是一个不同的问题。char* 指针 = new char[500] 你可以直接使用 std::string如果你正在进行输入/输出处理,请使用流“我的经理无法证明的某些事情” - 只要做就行了 :) - George Godik
@george 其实我这里不是在处理字符串,只是处理字节大小的数据而已。不过还是谢谢你 :) - krebstar
@krebstar 那么流就是正确的选择。在我看来,如果你要用C++编程,那么最好使用这些特性。 - George Godik

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接