C++ new关键字

说明:本文有理解和解释错误之处还请见谅

自己从接触new这个关键字,看了一些别人使用new的代码,知道new是自己在堆中申请的空间,但是一直不明白是怎么生成的。下面结合汇编来说一下new这个关键字。

一、用new申请存放基本类型的空间

1、申请一个整型数据,初始值为3

int* pa = new int(3);  //在堆中申请一个整型数据3,相当于int a = 3
/*观察汇编:
  push        4                   //编译器自己知道一个int的大小为4个字节  
  call        operator new (0D51320h)  //调用new,在堆中申请了4个字节的空间,将在堆中申请的的地址传递个EAX,此时0137FFB8
  add         esp,4  
  mov         dword ptr [ebp-110h],eax  //将EAX的值存放到栈中(此时0137FFB8存放在栈中)
  cmp         dword ptr [ebp-110h],0  
  je          Test+70h (0D524E0h)  
  mov         eax,dword ptr [ebp-110h]  
  mov         dword ptr [eax],3       //将要初始化的整型数值3存入地址为0x0137FFB8中(此时3在堆中)
  mov         ecx,dword ptr [ebp-110h]  
  mov         dword ptr [ebp-16Ch],ecx  
  jmp         Test+7Ah (0D524EAh)  
  mov         dword ptr [ebp-16Ch],0  
  mov         edx,dword ptr [ebp-16Ch]  //EDX = 0137FFB8
  mov         dword ptr [pa],edx  //将地址0x0137FFB8给pa,那么papa = 0x0137FFB8  03 00 00 00 
*/

new申请的空间是在堆中,但是我们定义的指针类型的pa是在栈中,之前一直不理解new之后的东西为什么必须是一个指针类型的变量接收,现在理解了,因为new之后返回的就是一个地址,一个地址啊,所以就用一个指针类型的变量来接收。。。


2、申请一个没有初始化的存放int类型的数组

int* pb = new int[3];
/*
00D524F3  push        0Ch  //编译器知道3个int的大小为12个字节
00D524F5  call        operator new[] (0D513ACh)  
00D524FA  add         esp,4  
00D524FD  mov         dword ptr [ebp-11Ch],eax  
00D52503  mov         eax,dword ptr [ebp-11Ch]  
00D52509  mov         dword ptr [pb],eax  //将在堆中申请的地址给指针pb,此时pb指针指向堆中的空间由cd填充,因为没有初始化
*/


3、申请一个默认用0初始化的存放int类型的数组(大小12个字节)

int* pd = new int[3]();//在堆中申请一个数组,数组大小为3个int,即3X4=12个字节,初始化为0,相当于int arr[3] = {};
/*
00D5251C  push        0Ch 
00D5251D  call        operator new[] (0D513ACh)  //调用new,将申请的地址返回给eax
00D52522  add         esp,4  
00D52525  mov         dword ptr [ebp-134h],eax  
00D5252B  cmp         dword ptr [ebp-134h],0  
00D52532  je          Test+0EAh (0D5255Ah)  
00D52534  mov         ecx,dword ptr [ebp-128h]  
00D5253A  push        ecx  
00D5253B  push        0  
00D5253D  mov         edx,dword ptr [ebp-134h]  
00D52543  push        edx  
00D52544  call        _memset (0D5110Eh)  //调用memset函数,数组里面是值默认用0初始化
00D52549  add         esp,0Ch  
00D5254C  mov         eax,dword ptr [ebp-134h]  
00D52552  mov         dword ptr [ebp-16Ch],eax  
00D52558  jmp         Test+0F4h (0D52564h)  
00D5255A  mov         dword ptr [ebp-16Ch],0  
00D52564  mov         ecx,dword ptr [ebp-16Ch]  
00D5256A  mov         dword ptr [pd],ecx  //将在堆中申请的地址给指针pc,此时pc指针指向堆中的空间由0填充
*/

二、用new申请存放类(或结构体)类型的空间

class A
{
	int i;
public:
	//A() {};
	A(int _i) :i(_i*_i) {}
	void Say() { printf("i=%d/n", i); }
};
A* Cpa = new A(3);
/*
00D52654  push        4  
00D52656  call        operator new (0D51320h)  //调用new,地址放到eax,此时eax=01378120
00D5265B  add         esp,4  
00D5265E  mov         dword ptr [ebp-164h],eax  
00D52664  mov         dword ptr [ebp-4],0  
00D5266B  cmp         dword ptr [ebp-164h],0  
00D52672  je          Test+219h (0D52689h)  
00D52674  push        3  
00D52676  mov         ecx,dword ptr [ebp-164h]  
00D5267C  call        A::A (0D51096h)         //调用类的构造函数,将实参3传入构造函数,运算之后的值存入到eax指向的地址中(堆中存放的值我为9)
00D52681  mov         dword ptr [ebp-16Ch],eax  
00D52687  jmp         Test+223h (0D52693h)  
A* Cpa = new A(3);
00D52689  mov         dword ptr [ebp-16Ch],0  
00D52693  mov         eax,dword ptr [ebp-16Ch]  
00D52699  mov         dword ptr [ebp-158h],eax  
00D5269F  mov         dword ptr [ebp-4],0FFFFFFFFh  
00D526A6  mov         ecx,dword ptr [ebp-158h]  
00D526AC  mov         dword ptr [Cpa],ecx  
*/

对于A* Cpa = new A(3);这句话相当于下面三句话(参考:http://blog.csdn.net/songthin/article/details/1703966)
A* pa = (A*)malloc(sizeof(A));
pa->A::A(3);
return pa;

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值