【问题标题】:delete[] and memory leaksdelete[] 和内存泄漏
【发布时间】:2010-11-19 04:19:53
【问题描述】:

我想知道 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;

指针指向的内存被删除了对吧?所以这意味着pointerIt现在没有指向有效内存..但这没关系,因为我可以将两个指针都设置为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+500吗?还是将pointerFirstPos指向的内存块删除到pointerFirstPos +500?

这会导致内存泄漏吗?

对于冗长的信息,我很抱歉,我正在努力清楚地传达我的信息。

谢谢,

克雷布

【问题讨论】:

  • "但这没关系,因为我可以将两个指针都设置为 NULL,对吗?"好吧,你应该完成指针......

标签: c++ visual-c++ memory-management memory-leaks


【解决方案1】:

第一个问题集:

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,对吗?

内存pointer 保存地址完全删除是的。 pointerpointerIt 都持有无效内存的地址。每个指针只是一个变量,每个变量都是独立的。因此,两者都彼此独立地存储自己的地址。取消引用运算符 * 只会为您提供该地址处的变量。该地址处的变量与指针变量是不同的变量。

第三题:

您应该只删除分配的地址,即整个数组。如果您尝试删除部分数组,您将得到未定义的结果。它会导致内存泄漏吗?可能,它会导致崩溃吗?可能,它会导致......?可能。

所以只删除您分配的内容。如果您分配一个数组,则使用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

【讨论】:

  • 除了使用 newnew[] 创建的内容之外,它未定义为 deletedelete[]
  • 谢谢,这正是我所怀疑的。但是说,比如在第三个问题集中,我设置了pointerIt = pointerFirstPosition,然后delete[] pointerIt,这还是undefined吗?我正在使用其他人的旧代码,他已经离开了公司,我正在试图弄清楚这是否是内存泄漏的原因..
  • 只是为了好玩,我在 g++ 4.4.1 下对此进行了测试——除了pointerIt 移动到数组的一半之外,基本上与您在第三个代码示例中得到的代码相同。在 pointerIt 上调用 delete[] 会使 pointer 无效,但显然如果行为未定义,则每个编译器都不会出现这种行为。
  • @krebstar:我想我在第 3 节中已经介绍过了。
  • 感谢 Meredith,我不太关心指针是否失效,而是内存是否真正被释放。我想我的问题是,运行第三组是否会导致 250 字节泄漏(pointerIt 的最后一个位置之前的 250 字节位置)?它是否会通过释放未分配的内存来破坏 pointerFirstPos+500 之后的 250 个内存位置?谢谢:)
【解决方案2】:

查看 boost::shared_ptr 或 boost::scoped_ptr,再也不用担心这个了。 这为您提供了一种静态和引用计数的方式来管理您的内存。

http://www.boost.org/doc/libs/1_39_0/libs/smart_ptr/shared_ptr.htm

【讨论】:

  • 如果我这样做,我将不得不修改这么多项目.. :( 我的经理无法证明这一点。
  • 对于未来的代码,那么。另外,请使用std::vector 和 kin。 永远没有手动分配内存。
  • @George:请注意,代码需要shared_array。 (或者,实际上,std::vector。)
  • @krebstar 这是一个不同的问题。 char* pointer = new char[500] 如果你正在做 i/o 处理,你可以只使用 std::string,使用流“我的经理无法证明的事情” - 就这样做:)
  • @george 其实我不是在这里处理字符串,实际上只是字节大小的数据.. 无论如何谢谢 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-11-06
  • 2012-12-07
  • 2010-11-14
  • 1970-01-01
  • 2013-05-13
  • 2010-12-02
  • 2013-11-08
相关资源
最近更新 更多