English 中文(简体)
删除
原标题:Is delete[] equal to delete?
  • 时间:2009-10-12 08:27:44
  •  标签:
IP_ADAPTER_INFO *ptr=new IP_ADAPTER_INFO[100];

如果是免费,

delete ptr;

如果不是这样,它会导致记忆泄露?

这是2005年VS2005年产生的拆解法

; 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 
最佳回答

这是否导致记忆泄露,wi住你的硬盘,使你怀孕,使纳萨尔人nas在你的公寓周围,或者让一切工作不明显问题,这是没有定义的。 这样做的方法可能是由一个汇编者进行,并与另一个汇编者进行改动,采用新的汇编版本,每一份新汇编,并附有月球阶段、你的 mo版,或者取决于最后一天下午通过加工商的内分因数。 也可能不是。

所有这一切,以及数量有限的其他可能性都包含在一个术语上:未界定的行为:

只是停留在它之外。

问题回答

仅举例说明某些顾问和汇编者的一些“未界定”行为。 希望能够帮助人们改变其法典。

试验1

#include <iostream>
using namespace std;
int main()
{
  int *p = new int[5];
  cout << "pass" << endl;
  delete p;
  return 0;
}

试验2

#include <iostream>
using namespace std;
int main()
{
  int *p = new int;
  cout << "pass" << endl;
  delete[] p;
  return 0;
}

试验3

#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

#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. Compile with default options, i.e. exception handler is enabled.

试验1

pass

试验2

pass

试验3

construct
construct
construct
construct
construct
pass
destroy
# Then, pop up crash msg

试验4

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 or gcc-4.8 generate the same output

试验1

pass

试验2

pass

试验3

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

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

pass

试验2

pass

试验3

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

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

通常不会泄露,因为如果是POD destructors,就没有必要援引这些器具del。 记忆性交易只需要一点点值,才能将其归还给肥皂。 阵列还积存一个毗连的记忆组,因此,如果是单一元素的所在地,则会发生交易。

但这并不取决于这一点,因为它不明确。 或许,如果它能干一切,也许会发生一些可怕的情况,就在这个汇编者上工作,不去为他人工作,许多人会感谢你制造错误。

,详见

delete : calls the appropriate destructor only for the element pointed to (if needed), then frees the memory chunk

delete[] : calls the appropriate destructors for each element in its array (if needed), then frees the memory chunk

利用新的T[n]分配的操作员,un Defin<>m>,从汇编者到汇编者将有所不同。 例如,AFAIK, MSVC的编纂者将产生与海合会不同的法典。

如果通过新的T[n]分配的阵列有点,则你必须删除。 A. 导 言 删除和删除[]之间的区别是直截了当的——前者摧毁一个cal子,后者摧毁一个阵列。





相关问题