执行期语意学——new和delete运算符

6.2.1 针对数组的new语意

Point类的定义,一个Point对象的大小是16个字节(3个float成员外加一个vptr):

class Point
{
public:
	Point(float x = 0.0, float y = 0.0, float z = 0.0) : _x(x), _y(y), _z(z)	{ }
	~Point(){};
	virtual void somefuc() {};
private:
	float _x, _y, _z;
};
main函数中动态申请含有10个Point对象的数组
int main(int argc, char* argv[])
{
	Point *ppp = new Point[10];
	delete []ppp;
}

看一下在VC6.0中针对数组的new语意是什么样的。main函数的汇编代码:

159:      Point *ppp = new Point[10];
0040149D push        0A4h 	                                                 //operator new的参数,也就是需要为数组申请的内存大小,多申请了4个字节,用于存储cookie(元素个数)
004014A2 call        operator new (00408930) 	                              // 调用operator new函数,调用结束后,EAX中存储了申请到的内存地址0x00941198
004014A7 add         esp,4
004014AA mov         dword ptr [ebp-18h],eax 	                               // 在栈上保存内存地址
004014AD mov         dword ptr [ebp-4],0
004014B4 cmp         dword ptr [ebp-18h],0                                   // 判断内存申请是否成功
004014B8 je          main+78h (004014e8)                                     // 申请内存失败跳过调用eh vector constructor iterator
004014BA push        offset @ILT+0(Point::~Point) (00401005)		// Point解构函数地址入栈
004014BF push        offset @ILT+5(Point::`default constructor closure') (0040100a)// Point默认构造函数地址入栈
004014C4 mov         eax,dword ptr [ebp-18h] 				// 申请到的内存地址存入EAX
004014C7 mov         dword ptr [eax],0Ah 				// 将数组元素个数存入申请到的内存首地址中,也就是上面说的cookie
004014CD push        0Ah 						// 数组元素个数入栈
004014CF push        10h 						// Point对象的大小
004014D1 mov         ecx,dword ptr [ebp-18h] 				// 申请到的内存地址放入ECX
004014D4 add         ecx,4 						// 内存地址加4,跳过了cookie,做为数组的地址
004014D7 push        ecx 						// 数组地址入栈
004014D8 call        `eh vector constructor iterator' (00408890) 	// 调用eh vector constructor iterator,在该函数会对数组元素逐一调用构造函数
004014DD mov         edx,dword ptr [ebp-18h] 				// 内存地址放入EDX
004014E0 add         edx,4 						// EDX加4,成为数组地址
004014E3 mov         dword ptr [ebp-24h],edx 				// 数组地址放入一个临时变量中
004014E6 jmp         main+7Fh (004014ef)
004014E8 mov         dword ptr [ebp-24h],0 				// 申请内存失败时,临时变量设为0 
004014EF mov         eax,dword ptr [ebp-24h]
004014F2 mov         dword ptr [ebp-14h],eax
004014F5 mov         dword ptr [ebp-4],0FFFFFFFFh
004014FC mov         ecx,dword ptr [ebp-14h]
004014FF mov         dword ptr [ebp-10h],ecx 				// 将数组地址赋给ppp
160:      delete []ppp;
00401502 mov         edx,dword ptr [ebp-10h] 				//
00401505 mov         dword ptr [ebp-20h],edx 				//
00401508 mov         eax,dword ptr [ebp-20h] 				//
0040150B mov         dword ptr [ebp-1Ch],eax 				// 倒腾来倒腾去的折腾啥?EDX、EAX、ebp-10h、ebp-20h、ebp-1Ch全都是数组地址
0040150E cmp         dword ptr [ebp-1Ch],0 				// 判断数组地址是否为空
00401512 je          main+0B3h (00401523)
00401514 push        3
00401516 mov         ecx,dword ptr [ebp-1Ch] 				// 数组地址放入ECX
00401519 call        @ILT+15(Point::`vector deleting destructor') (00401014)// 在此函数中调用解构函数之后,调用delete释放内存,释放内存时会减4转为原始内存地址
0040151E mov         dword ptr [ebp-28h],eax
00401521 jmp         main+0BAh (0040152a)
00401523 mov         dword ptr [ebp-28h],0
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值