class下的new delete

class test
{
public:
    test(){printf("constructor/n");};
    ~test() {printf("destuctor/n");}
};

void main()
{
    test *t = new test[12];
    delete t;

}

vc6编译,ida反编译如下:

int __cdecl main(int argc, const char **argv, const char **envp)
{
  void *v3; // eax@1
  int result; // eax@2
  int v5; // esi@2
  void *v6; // esi@5

  v3 = operator new(0x10u);
  if ( v3 )
  {
    v5 = (int)((char *)v3 + 4);
    *(_DWORD *)v3 = 12;  //数组长度,放在开辟空间的前四个字节
    _eh_vector_constructor_iterator_((char *)v3 + 4, 1, 12, sub_401090, sub_4010B0);
    //sub_401090为构造函数,sub_4010B0为析构
    result = v5;  //开辟出空间的第5个字节地址返回给test *t
  }
  else
  {
    result = 0;
  }
  if ( result )   //编译优化后的delete,先判断result是否为空,所以很多人习惯写的if (t!=null) delete t是没必要的
  {
    v6 = (void *)(result - 4);
    _eh_vector_destructor_iterator_(result, 1, *(_DWORD *)(result - 4), sub_4010B0);
    result = sub_4010C0(v6);  //删除内存,内部直接调用的heapfree,没有对free的调用
  }
  return result;
}

对new的调用,我们可以看到vc6确实是在为非内置类型数据成员开辟空间的时候,多开辟了一个长度,而且长度是放在这开辟出来内存的前四个字节中,相当于调用了malloc(size+4),然后全部执行构造函数

但是delete调用就不一样了,这里没有对free函数的调用,因为他多了一个代表长度的字节,没法用原有的库函数了,只能从写了一个方法

综上,

1,delete 加不加[]对系统内置类型int double之类,没有关系,这个情况下new delete最终是和malloc free调用同样的代码

2,非内置类型的情况下,delete 才是一定加[],虽然到现在我还是不明白,为什么不可以学习free的方式使用__sbh_find_block等函数获取实际大小,然后根据大小来析构,难道是以空间换时间?

所以说new必然调用malloc是可以的,delete必然调用free是不正确的,或许在不同的编译器下面有不同的表现,欢迎高手指教



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值