请问下面这段代码为什么会导致析构函数无限递归

Microsues 2010-12-09 09:44:25
class base
{
public:
base() {p = this;cout<<"base()"<<endl;}
~base()
{
if(p != NULL)
{
cout<<"~base()"<<endl;
// delete p; //为什么执行这条语句会导致无限递归?????????????????
//delete把p指向的对象删除了,但p里面仍然存放着this,
p=NULL;
}
}
protected:
base *p;
};

void main()
{
base bobj;
}
...全文
315 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
海枫 2010-12-10
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 yuyan_linger 的回复:]

这里用delete是有问题的 可能他侧重点在递归调用 所以没有按规矩来
[/Quote]

晕,尽管我没有写过C++代码,但我还是能看得出来,这里的delete是规规矩矩的。 不要给人家(delete)乱套帽子
yuyan_linger 2010-12-10
  • 打赏
  • 举报
回复
这里用delete是有问题的 可能他侧重点在递归调用 所以没有按规矩来
Microsues 2010-12-10
  • 打赏
  • 举报
回复
谢谢哈,理解啦
还有一个疑问是:我知道的delete只能释放动态分配的内存,为什么这里可以使用delete?
[Quote=引用 1 楼 hnuqinhuan 的回复:]

base *p;
因为你的p的类型是 base 使用了自嵌入 相当于在无限循环
delete p是删除base 又会调用 base里面的 delete 接着又会调用base的delete
这样无限循环了
[/Quote]
Microsues 2010-12-10
  • 打赏
  • 举报
回复
理解啦,多谢指点哈
[Quote=引用 11 楼 arcticanimal 的回复:]

再补一点,更清楚:
C/C++ code

// class base 的析构函数会编译成如下形式
void base_destructor(T* );

// 这是delete 展开之后的伪代码
operator delete(base* p)
{
base_destructor(p);
free(p);
}

// base 的析构函数实现
void base_destr……
[/Quote]
Microsues 2010-12-10
  • 打赏
  • 举报
回复
理解了,多谢指点
[Quote=引用 10 楼 arcticanimal 的回复:]

楼主你要知道 C++ 的 delete 操作符是怎么一回事

delete 操作符会被编译器展开为至少两个子过程
1. 调用所传入类型的析构函数(如果是虚析构函数,之后还会去调用子类的析构函数)
2. 调用内存销毁函数,释放所传入指针指向的内存

对非动态分配的对象调用delete,第一个过程是不会有问题的,但是第二个过程就会让你的程序挂掉
楼主的代码在析构函数中调用delete,……
[/Quote]
Arcticanimal 2010-12-10
  • 打赏
  • 举报
回复
再补一点,更清楚:

// class base 的析构函数会编译成如下形式
void base_destructor(T* );

// 这是delete 展开之后的伪代码
operator delete(base* p)
{
base_destructor(p);
free(p);
}

// base 的析构函数实现
void base_destructor(T* p)
{
delete(p);
}


上面的伪代码就很清楚了
Arcticanimal 2010-12-10
  • 打赏
  • 举报
回复
楼主你要知道 C++ 的 delete 操作符是怎么一回事

delete 操作符会被编译器展开为至少两个子过程
1. 调用所传入类型的析构函数(如果是虚析构函数,之后还会去调用子类的析构函数)
2. 调用内存销毁函数,释放所传入指针指向的内存

对非动态分配的对象调用delete,第一个过程是不会有问题的,但是第二个过程就会让你的程序挂掉
楼主的代码在析构函数中调用delete,会在第一个子过程中形成无限递归,不会执行到第二个子过程。所以楼主的代码会正常的无线递归。
Microsues 2010-12-10
  • 打赏
  • 举报
回复
这个代码在VS2008下没任何编译和运行错误,结果是命令行显示:无限输出~base()
[Quote=引用 8 楼 chrome029 的回复:]

delete的使用坚持和new配对,坚持谁new谁delete,楼主这个代码相当的强大
[/Quote]
还没想好 2010-12-10
  • 打赏
  • 举报
回复
delete的使用坚持和new配对,坚持谁new谁delete,楼主这个代码相当的强大
nicklisir 2010-12-09
  • 打赏
  • 举报
回复
支持
[Quote=引用 1 楼 hnuqinhuan 的回复:]
base *p;
因为你的p的类型是 base 使用了自嵌入 相当于在无限循环
delete p是删除base 又会调用 base里面的 delete 接着又会调用base的delete
这样无限循环了
[/Quote]
就想叫yoko 2010-12-09
  • 打赏
  • 举报
回复
如果你构造函数坚持要p=this的话
那么你的析构函数是没有必要delete p的
因为对象过了生存周期自己会释放
foxpeter 2010-12-09
  • 打赏
  • 举报
回复
base() {p = new base;cout<<"base()"<<endl;} 这样比较好吧
無_1024 2010-12-09
  • 打赏
  • 举报
回复
base *p;
因为你的p的类型是 base 使用了自嵌入 相当于在无限循环
delete p是删除base 又会调用 base里面的 delete 接着又会调用base的delete
这样无限循环了

64,318

社区成员

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

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