防水led灯管:[C++] 关于delete和delete[]

来源:百度文库 编辑:九乡新闻网 时间:2024/05/06 12:28:29
首先贴一段MFC的源代码:
void __cdecl operator delete(void* p)
{
free(p);
}
void __cdecl operator delete[](void* p)
{
::operator delete(p);
}
然后贴一点汇编:
char* p = new char[100];
00402CE1  push        64h
00402CE3  call        operator new[] (4051C6h)
00402CE8  add         esp,4
00402CEB  mov         dword ptr [ebp-7Ch],eax
00402CEE  mov         eax,dword ptr [ebp-7Ch]
00402CF1  mov         dword ptr [p],eax
delete p;
00402CF4  mov         eax,dword ptr [p]
00402CF7  mov         dword ptr [ebp-78h],eax
00402CFA  mov         ecx,dword ptr [ebp-78h]
00402CFD  push        ecx
00402CFE  call        operator delete (4051C1h)
00402D03  add         esp,4
delete [] p;
00402D06  mov         eax,dword ptr [p]
00402D09  mov         dword ptr [ebp-74h],eax
00402D0C  mov         ecx,dword ptr [ebp-74h]
00402D0F  push        ecx
00402D10  call        operator delete[] (4051CBh)
00402D15  add         esp,4
分析:
其中的call operator delete (4051C1h) 就是去调用MFC的void __cdecl operator delete(void* p)
其中的call operator delete[] (4051CBh) 就是去调用MFC的void __cdecl operator delete[](void* p)
所以在这种情下,两者是完全等效的。
A* a = new A[100];
00402D18  push        194h
00402D1D  call        operator new[] (4051C6h)
00402D22  add         esp,4
00402D25  mov         dword ptr [ebp-6Ch],eax
00402D28  mov         dword ptr [ebp-4],0
00402D2F  cmp         dword ptr [ebp-6Ch],0
00402D33  je          CTestMFCDlg::OnBnClickedButton9+0A3h (402D63h)
00402D35  mov         eax,dword ptr [ebp-6Ch]
00402D38  mov         dword ptr [eax],64h
00402D3E  push        offset A::~A (402E00h)
00402D43  push        offset A::A (402DE0h)
00402D48  push        64h
00402D4A  push        4
00402D4C  mov         ecx,dword ptr [ebp-6Ch]
00402D4F  add         ecx,4
00402D52  push        ecx
00402D53  call        `eh vector constructor iterator' (443BA8h)
00402D58  mov         edx,dword ptr [ebp-6Ch]
00402D5B  add         edx,4
00402D5E  mov         dword ptr [ebp-80h],edx
00402D61  jmp         CTestMFCDlg::OnBnClickedButton9+0AAh (402D6Ah)
00402D63  mov         dword ptr [ebp-80h],0
00402D6A  mov         eax,dword ptr [ebp-80h]
00402D6D  mov         dword ptr [ebp-70h],eax
00402D70  mov         dword ptr [ebp-4],0FFFFFFFFh
00402D77  mov         ecx,dword ptr [ebp-70h]
00402D7A  mov         dword ptr [a],ecx
delete a;
00402D7D  mov         eax,dword ptr [a]
00402D80  mov         dword ptr [ebp-64h],eax
00402D83  mov         ecx,dword ptr [ebp-64h]
00402D86  mov         dword ptr [ebp-68h],ecx
00402D89  cmp         dword ptr [ebp-68h],0
00402D8D  je          CTestMFCDlg::OnBnClickedButton9+0DEh (402D9Eh)
00402D8F  push        1
00402D91  mov         ecx,dword ptr [ebp-68h]
00402D94  call        A::`scalar deleting destructor' (402EA0h)
00402D99  mov         dword ptr [ebp-80h],eax
00402D9C  jmp         CTestMFCDlg::OnBnClickedButton9+0E5h (402DA5h)
00402D9E  mov         dword ptr [ebp-80h],0
delete [] a;
00402DA5  mov         eax,dword ptr [a]
00402DA8  mov         dword ptr [ebp-5Ch],eax
00402DAB  mov         ecx,dword ptr [ebp-5Ch]
00402DAE  mov         dword ptr [ebp-60h],ecx
00402DB1  cmp         dword ptr [ebp-60h],0
00402DB5  je          CTestMFCDlg::OnBnClickedButton9+106h (402DC6h)
00402DB7  push        3
00402DB9  mov         ecx,dword ptr [ebp-60h]
00402DBC  call        A::`vector deleting destructor' (402E20h)
00402DC1  mov         dword ptr [ebp-80h],eax
00402DC4  jmp         CTestMFCDlg::OnBnClickedButton9+10Dh (402DCDh)
00402DC6  mov         dword ptr [ebp-80h],0
分析:
其中的call  A::`scalar deleting destructor' (402EA0h) 会call A::~A (402E00h) 然后call operator delete (4051C1h)
其中的call  A::`vector deleting destructor' (402E20h)会循环的为每个对象call  `eh vector destructor iterator' (443C7Dh) 循环结束之后call operator delete[] (4051CBh)
结论:
1,对于char这样的基础数据类型,delete和delete[]是等价的。
2,对于class A这样带析构函数的类型,delete和delete[]是不同的。
3,如果只有一个对象,那么对象数组在逻辑上可以蜕化成一个对象,但是那样会多一些步骤,性能会稍差一些。这大概是C++需要同时保留delete和delete[]的原因。