首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >delete[]是否等于delete?

delete[]是否等于delete?
EN

Stack Overflow用户
提问于 2009-10-12 08:27:45
回答 6查看 12.1K关注 0票数 47
代码语言:javascript
复制
IP_ADAPTER_INFO *ptr=new IP_ADAPTER_INFO[100];

如果我免费使用

代码语言:javascript
复制
delete ptr;

它会导致内存泄漏吗?如果不会,为什么?

这是由VS2005生成的反汇编代码

代码语言:javascript
复制
; delete ptr;
0041351D  mov         eax,dword ptr [ptr] 
00413520  mov         dword ptr [ebp-0ECh],eax 
00413526  mov         ecx,dword ptr [ebp-0ECh] 
0041352C  push        ecx  
0041352D  call        operator delete (4111DBh) 
00413532  add         esp,4 

; delete []ptr;
00413535  mov         eax,dword ptr [ptr] 
00413538  mov         dword ptr [ebp-0E0h],eax 
0041353E  mov         ecx,dword ptr [ebp-0E0h] 
00413544  push        ecx  
00413545  call        operator delete[] (4111E5h) 
0041354A  add         esp,4 
EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2009-10-12 08:41:47

这是否会导致内存泄漏,擦除你的硬盘,让你怀孕,让讨厌的鼻魔在你的公寓里追着你,还是让一切正常工作而没有明显的问题,都是未知的。对于一个编译器,可能是这样的,并且随着另一个编译器的变化,随着新的编译器版本的变化,随着每次新的编译,随着月相,你的情绪,或者取决于在最后一个晴朗的下午通过处理器的中微子的数量。也有可能不是。

所有这些,以及无限多的其他可能性可以归结为一个术语:未定义的行为:

离它远点。

票数 154
EN

Stack Overflow用户

发布于 2013-09-24 12:54:36

只是对某些OSes和编译器上的一些“未定义”行为的说明。希望它能帮助人们调试他们的代码。

测试1

代码语言:javascript
复制
#include <iostream>
using namespace std;
int main()
{
  int *p = new int[5];
  cout << "pass" << endl;
  delete p;
  return 0;
}

测试2

代码语言:javascript
复制
#include <iostream>
using namespace std;
int main()
{
  int *p = new int;
  cout << "pass" << endl;
  delete[] p;
  return 0;
}

测试3

代码语言:javascript
复制
#include <iostream>
using namespace std;
struct C {
  C() { cout << "construct" << endl; }
  ~C() { cout << "destroy" << endl; }
};

int main()
{
  C *p = new C[5];
  cout << "pass" << endl;
  delete p;
  return 0;
}

测试4

代码语言:javascript
复制
#include <iostream>
using namespace std;
struct C {
  C() { cout << "construct" << endl; }
  ~C() { cout << "destroy" << endl; }
};

int main()
{
  C *p = new C;
  cout << "pass" << endl;
  delete[] p;
  return 0;
}

  • Windows 7 x86,msvc 2010。使用默认选项进行编译,即启用了异常处理程序。

测试1

代码语言:javascript
复制
pass

测试2

代码语言:javascript
复制
pass

测试3

代码语言:javascript
复制
construct
construct
construct
construct
construct
pass
destroy
# Then, pop up crash msg

测试4

代码语言:javascript
复制
construct
pass
destroy
destroy
destroy
destroy
destroy
destroy
destroy
... # It never stop until CTRL+C

  • Mac OS X 10.8.5、llvm-gcc 4.2或gcc-4.8生成相同的输出

测试1

代码语言:javascript
复制
pass

测试2

代码语言:javascript
复制
pass

测试3

代码语言:javascript
复制
construct
construct
construct
construct
construct
pass
destroy
a.out(71111) malloc: *** error for object 0x7f99c94000e8: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
zsh: abort      ./a.out

测试4

代码语言:javascript
复制
construct
pass
a.out(71035) malloc: *** error for object 0x7f83c14000d8: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
zsh: abort      ./a.out

  • Ubuntu 12.04,AMD64,gcc 4.7

测试1

代码语言:javascript
复制
pass

测试2

代码语言:javascript
复制
pass

测试3

代码语言:javascript
复制
construct
construct
construct
construct
construct
*** glibc detected *** ./a.out: munmap_chunk(): invalid pointer: 0x0000000001f10018 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x7eb96)[0x7fe81d878b96]
./a.out[0x400a5b]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xed)[0x7fe81d81b76d]
./a.out[0x4008d9]
======= Memory map: ========
....
zsh: abort (core dumped)  ./a.out

测试4

代码语言:javascript
复制
construct
destroy
destroy
destroy
destroy
destroy
destroy
destroy
destroy
...
destroy
destroy
*** glibc detected *** ./a.out: free(): invalid pointer: 0x00000000016f6008 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x7eb96)[0x7fa9001fab96]
./a.out[0x400a18]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xed)[0x7fa90019d76d]
./a.out[0x4008d9]
======= Memory map: ========
...
zsh: abort (core dumped)  ./a.out
票数 14
EN

Stack Overflow用户

发布于 2009-10-12 08:55:32

它通常不会泄漏,因为在POD的情况下,析构函数是微不足道的,并且不需要调用它们,所以delete只是释放由数组占用的内存。内存释放只需要一个指针值,因此它将被返回给堆。数组占用一个连续的内存块,因此释放可以是成功的,就像它是单个元素的释放一样。

但不要依赖于此,因为它是未定义的行为。也许它可以正常工作,也许会发生一些可怕的事情,在这个编译器上工作,在另一个编译器上不工作,很多人感谢你植入了一个错误。

详情请参见this answer

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1553382

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档