new和delete成对使用_一个博客id_新浪博客

new:开辟内存,调用构造函数
delete:调用析构函数,释放内存


class Test
{
   Test(){}
   ~Test(){}
};

对于new单个对象和多个对象的数组,内存布局是有一些差别的。

Test * p1 = new Test;
Test * p2 = new Test[6];

单个对象和多个对象的内存布局:
new和delete成对使用
1.
Test * p1 = new Test;
delete []p1;
delete看到是[]p1,他会去前四字节查看确定要调用多少次析构函数,我猜测这样会越界访问,因为实际上就没有分配这四个字节,实际上这个错误是未定义的。


2.
Test * p2 = new Test[6];
delete p2;
delete看到的是p,指向对象的普通指针,不是数组,释放的时候他可能只会调用一次析构函数,前四个字节造成内存陷漏的问题。


总结:使用的时候我们只要配对使用就好了。







##############################################################################


代码测试:
在operator new中打印出返回给用户的内存的起始地址;
在operator delete中打印出实际释放的内存的起始地址;

class Test

{

public:

Test(){ cout << "Test()" << endl; }

~Test(){ cout << "~Test()" << endl; }

 

void* operator new(size_t size)

{

void *p = NULL;

p = malloc(size);

cout << "addr:" << p << endl;

return p;

}

void operator delete(void *ptr)

{

cout << "addr:" << ptr << endl;

free(ptr);

}

void* operator new[](size_t size)

{

void *p = NULL;

p = malloc(size);

cout << "addr:" << p << endl;

return p;

}

void operator delete[](void *ptr)

{

cout << "addr:" << ptr << endl;

free(ptr);

}


测试一结果:
Test *p2 = new Test;
delete []p2;
new和delete成对使用
编译器给用户返回的是90,实际开始释放的地址是8C,在调用析构函数的时候挂掉了,访问越界。
因为它看到的是[]p 所以认为释放要先向上偏移四个字节 8C-4

测试二:
Test *p1 = new Test[3];
delete p1;
new和delete成对使用

编译器给用户返回的是D8,释放的时候向下偏移4字节,对一大整块内存调用了一次析构函数。无论说是内存陷漏还是析构次数不够都是正确的,这个错误是未定义的。


测试一配对使用的结果:
Test *p2 = new Test;
 delete p2;
new和delete成对使用

测试二配对使用的结果:
Test *p1 = new Test[3];
delete []p1;
new和delete成对使用


void* operator new(size_t size)

{

 

void *p = NULL;

p = malloc(size);

if (p == NULL)

throw bad_alloc("");

return p;

}

void operator delete(void *ptr)

{

free(ptr);

}

void* operator new[](size_t size)

{

void *p = NULL;

p = malloc(size);

if (p == NULL)

throw bad_alloc("");

return p;

}

void operator delete[](void *ptr)

{

free(ptr);

}








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值