[讨论]如何处理构造函数中资源分配失败?

shadowstar 2003-12-25 03:18:32
C++太灵活了。。。
...全文
330 28 打赏 收藏 转发到动态 举报
写回复
用AI写文章
28 条回复
切换为时间正序
请发表友善的回复…
发表回复
hchinside 2003-12-30
  • 打赏
  • 举报
回复
class A
{
public:
A()
try : initialize list
{
.....
}
catch (...)
{}
}
这样可以处理初始化列表中的异常
sharkhuang 2003-12-29
  • 打赏
  • 举报
回复
你可以看看 more effcet c++

详细介绍
aaassd 2003-12-29
  • 打赏
  • 举报
回复
还有谁说,大师们都哪里去了?
shadowstar 2003-12-29
  • 打赏
  • 举报
回复
还有很多方法的,没人说,明天结贴吧。。。
jeckyz 2003-12-28
  • 打赏
  • 举报
回复
构造函数抛出异常本来就不是好方法(大师门通常是避而不谈,或者只是说不要这么干),但也确实没有很好的方法,我的看法是:干脆就 delete this 算了,可以抛出异常,但绝对不要在构造函数里处理它,因为这样很容易死循环的,在外部 catch 它,输出个错误信息。具体怎么处理,我想还是实际问题实际分析吧,因为构造错误肯定是个严重问题,很难有一个定则,或许把别的错误解决了,这个问题也就迎韧而解了。
shadowstar 2003-12-28
  • 打赏
  • 举报
回复
处理构造函数失败难道不包括异常处理的方式么?

[quote Jinhao(辣子鸡丁)]
我上面的代码没有用异常而直接进行delete this;导致a=new A;进行了赋值,我是故意这样做的,原因是构造函数未完成,对象就不会构造成功,delete this;就毫无意义,如果有了delete this;会带来极其隐蔽的BUG。
[/quote]

首先你不应该故意这么做! 即使有异常发生构造还是完成了。

这个版好象很多人的嘛,看来大家对这个不感兴趣。
唉,没意思。。。
Jinhao 2003-12-28
  • 打赏
  • 举报
回复
楼主的问题已经从[如何处理构造函数中资源分配失败]讨论到[是否在构造函数的异常处理中需要delete this;]
我上面的代码没有用异常而直接进行delete this;导致a=new A;进行了赋值,我是故意这样做的,原因是构造函数未完成,对象就不会构造成功,delete this;就毫无意义,如果有了delete this;会带来极其隐蔽的BUG。
当然用了异常更好,他会阻止后面的动态分配
shadowstar 2003-12-28
  • 打赏
  • 举报
回复
Jinhao(辣子鸡丁)
这样写当然一点意义都没有了,而且还有个大BUG。
要改成这样的:

A(){
delete this; //有了delete this;
throw(-1);
}

int main(int argc, char* argv[])
{
A* a = NULL; // 初始化指针变量为NULL
B* b = NULL; // 养成好习惯

try {
a = new A();
b = new B();
} catch(...) {
delete a; // 此时 a == NULL,delete也不会出错
delete b; // 正确
}

return 1;
}
Jinhao 2003-12-28
  • 打赏
  • 举报
回复
楼主,你先仔细看完下面的代码
class A
{
public:
A(){
delete this; //有了delete this;
}
~A(){
cout<<"Deleted A"<<endl;
}
};

class B{};

int main()
{
A* a;
B* b;
a=new A;
b=new B;
delete a;
....省掉很多对class B实例对象操作的代码
delete b;
}
这段代码看上去毫无问题,其实有个严重的BUG隐藏在class A的默认构造函数中。你会发现程序会在...处和delete b;处出错
那是因为A的默认构造函数中的delete this;导致B的实例对象分配在A的this指针所指的内存上,当你delete a;就破坏了B实例对象的堆内存
shadowstar 2003-12-28
  • 打赏
  • 举报
回复
delete this;
会调用析构函数,所以不需要在构造函数中delete[] pA;
transformers 2003-12-27
  • 打赏
  • 举报
回复
初学者问:

“但是如果遇到pA=new A[10];这样分配的话,你用delete this;就破坏了堆,当你delete []pA;就有问题了”

破坏了堆 是什么意思? 能否给小弟解释一下! 谢了!
Jinhao 2003-12-27
  • 打赏
  • 举报
回复
绝对不用担心char* str[10];占用的内存
首先class A的构造函数并没有完成,这说明对象构造失败,这时抛出异常后,这个class A的实例对象占用的内存就被归还系统了。
我提供的这段代码中,可以用delete this;
但是如果遇到pA=new A[10];这样分配的话,你用delete this;就破坏了堆,当你delete []pA;就有问题了
shadowstar 2003-12-27
  • 打赏
  • 举报
回复
to Jinhao(辣子鸡丁)

在构造过程中,char* str[10];所占的内存是被分配了的,如果不用 delete this; 的话还是有一定浪费。
shadowstar 2003-12-27
  • 打赏
  • 举报
回复
请问delete []str[i]前面的“[]”是什么意思?

对应的 str[i]=new char[1024*1024*1024]; //要来就来狠的

表示删除数组。


Zaster 2003-12-27
  • 打赏
  • 举报
回复
请问delete []str[i]前面的“[]”是什么意思?
初学ing,请各位大侠不要吝啬啊,感激不尽。
Jinhao 2003-12-27
  • 打赏
  • 举报
回复
一个实例对象的构造
第一步,分配足够的内存,如果失败就是栈溢出或抛出std::bad_alloc的异常,所以在这步你不用担心内存泄露,而且这一步你是不能插手的,如果这步成功,就进入第二步
第二步,调用构造函数,在通常情况下,如果构造函数为空或没有进行动态内存分配,你就不用关心内存泄露了
你需要关心的是构造函数中有动态内存分配
class A
{
char* str[10];
public:
A(){
for(int i=0;i<10;i++)
str[i]=NULL; //对str[]初始化,这是必须的,不然再后面delete就会出现问题
try{
for(int i=0;i<10;i++)
str[i]=new char[1024*1024*1024]; //要来就来狠的
}
catch(bad_alloc){
for(int i=0;i<10;i++)
delete []str[i]; //放心,即使delete NULL是不会出问题的
//delete this;
throw; //就抛出这个bad_alloc
}
}
~A()
{
for(int i=0;i<10;i++)
delete []str[i];
}
};
int main()
{
A *pA=NULL;
try{
pA=new A;
}
catch(bad_alloc){
cout<<"Out of memory"<<endl;
}
delete pA;
return 0;
}
pA是用NULL初始化的,即使在给A分配内存时(第一步)失败,这样就不会导致后面的delete pA出错。
在class A 的构造函数中的异常处理中没有提供delete this;提供了就完了
shadowstar 2003-12-27
  • 打赏
  • 举报
回复
up
shadowstar 2003-12-26
  • 打赏
  • 举报
回复
too ALL

如何处理构造函数中资源分配失败?
肯定不只有异常一种方法,而且异常也不一定在任何情况下都是最好的方法。

以前的贴子我都翻过了,基本都说得是异常,没有一个全面的。提出这个问题只是希望抛砖引玉,和大家讨论一下各种方法所适用的环境。

象我上面的代码,抛出的异常,但实际上CFoo已经被构造了。有一个方法是在构造函数中删除自己,这样即没有给调用者返回指针,又不会造成资源泄漏。因为是独创,没见有人用过,所以想讨论一下。

CFoo() {
cout << "construct CFoo." << endl;
// an error occurred
delete this;
throw -1;
}

还有其它的方法,我不想一个人在这儿干吼,烦请各位高手出招。
transformers 2003-12-26
  • 打赏
  • 举报
回复
还有就是你用考虑吗?用异常不是很好吗!
transformers 2003-12-26
  • 打赏
  • 举报
回复
分配失败,Foo仍然是NULL吧?!

那还用什么delete?
加载更多回复(8)

64,637

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧