读书人

关于指向new的指针的疑义

发布时间: 2013-07-16 22:38:05 作者: rapoo

关于指向new的指针的疑问
假设有个Weight类(私有成员为指向Bitmap类的指针p)

定义赋值构造函数如下


Weight& Weight::operator=(const Weight& x)
{
if(this==&x)return *this;
delete p;
p=new Bitmap(*x.p);
return *this;
}


想问如果new Bitmap导致异常(如分配内存不足),那指针p会指向哪里?
[解决办法]
引用:
Quote: 引用:

指向刚刚被 delete 的那个地方.

也就是p不是空指针了吧。那下面这个改进函数能起到“异常安全性”的作用吗?effective C++ 条款11


Weight& Weight::operator=(const Weight& x)
{
Bitmap* Op=p;
p=new Bitmap(*x.p);
delete Op;
return *this;
}

这样不还是返回一个指向一块被删除的Bitmap?


这样写确实更安全。因为new失败时,将会抛出bad_alloc异常,后面的语句将不会执行,对p的赋值也不会执行,deleteOP不会发生,p没有发生改变,也没有被delete。这样在调用者用catch捕获并处理了异常之后,这个Weight对象依然处理正常状态。

不过,多数情况下bad_alloc异常的处理都是退出程序,所以是否安全也没有太大意义。
[解决办法]
引用:
假设有个Weight类(私有成员为指向Bitmap类的指针p)

定义赋值构造函数如下

Weight& Weight::operator=(const Weight& x)
{
if(this==&x)return *this;
delete p;
p=new Bitmap(*x.p);
return *this;
}


想问如果new Bitmap导致异常(如分配内存不足),那指针p会指向哪里?


如果分配失败,p和operator=内的其他变量会被析构、退栈。根本执行不到p=new这一步。

int * pout;
try
{
C o1;
int * p = new int;
*p = 0;
o1.f();
pout = p;
}
catch(std::bad_alloc)
{
pout = nullptr;
}

分配成功的执行路径(伪代码):

int * pout;
-->;
byte mem_o1[sizeof(C)];
((mem_o1 *))->C();
p = new int;
*p=0;
((mem_o1 *))->f();
pout = p;
((mem_o1 *))->~C();
--<;

分配失败的执行路径(伪代码):

int * pout;
-->;
byte mem_o1[sizeof(C)];


((mem_o1 *))->C();
new int;
__EXCP -->
((mem_o1 *))->~C();
pout = nullptr;
__EXCP --<
--<;

读书人网 >C++

热点推荐