C 破坏者回收
C++ destructor recycling
本文关键字:破坏者 更新时间:2023-10-16
我在网上看到了一个奇怪的c 代码,我想知道destructor中发生了什么。
我在网上查询了很多有关C 破坏者的知识,但我仍然没有找到答案。
#include <set>
#include <iostream>
using namespace std;
struct A;
struct B{
set<A*> sets;
~B(){
cout << " b destructor invoked" << endl;
};
};
struct A{
B* b;
~A(){
cout<< " a destructor invoked" << endl;
b->sets.erase(this);//here will produce error, but why?
}
};
int main(){
A a;
B b;
a.b = &b;
b.sets.insert(&a);
return 0;
}
上面的片段将产生以下错误。
out:
b destructor invoked
a destructor invoked
*** Error in `./a.out': double free or corruption (fasttop): 0x0000000001291c20
*** Aborted (core dumped)
此错误消息说我可能是双人免费的或损坏的。但是为什么?
但是,当我重写下面的结构B
时,所有错误都消失了。
struct B{
set<A*> sets;
~B(){
cout << " b destructor invoked" << endl;
sets.clear(); //use clear method on sets
};
};
当我在B
Destructor中使用clear()
方法时,所有错误都消失了。
out:
b destructor invoked
a destructor invoked
我不知道它的深层逻辑是什么。
问题:
为什么当我在B
struct中添加sets.clear()
时,错误消息会消失?
预先感谢!
b destructor invoked a destructor invoked
显然,B首先被销毁。这是因为变量以声明的相反顺序破坏。
当时,a.b
变得无效。它不再指向B对象。它用来指向的对象不再存在。接下来,a被摧毁。在其破坏者中,它试图通过通过无效的指针间接访问成员。该程序的行为不确定。
为什么当我在b struct中添加sets.clear((时,错误消息会消失?
因为程序的行为不确定。不能保证它会崩溃。
对于局部变量,破坏在构造方面发生了相反的顺序。
int main(){
A a;
B b;
a.b = &b;
b.sets.insert(&a);
// b destructed here
// a destructed here
return 0;
}
所以,当~A()
运行时,a.b
不再是有效的指针。
相关文章:
- 在放松试验块期间,通过投掷破坏者而导致这种怪异的行为
- 为什么我的虚拟破坏者多次执行这些执行
- 在销毁派生成员之前,在破坏者中调用共同功能
- 纯抽象类的虚拟破坏者
- 如何在CLION中的C 破坏者中达到断点
- 模拟一个函数,该函数像操作员=和破坏者一样传播到每个字段
- C :如何正确删除在类破坏者中的指针
- C 破坏者回收
- 模板基类的破坏者中的类型完整性不一致
- 使用std :: map时,包含unique_ptr的结构中的默认破坏者会导致编译错误
- 为什么我的破坏者只称呼一次,而不是在删除(a)调用上
- 与虚拟破坏者相比,Shared_PTR的运行时开销用于子类破坏
- 定义或声明类破坏者时,C 使用已删除的函数
- 在另一类中使用受保护的破坏者删除对象
- 永远循环的链接列表破坏者
- 不同版本的破坏者称为奇怪因素
- 将std :: lock_guard固定在破坏者中是安全的吗?
- 已经被破坏的一系列物体上的破坏者
- 即使在明确调用破坏者后,对象自动破坏也是如此
- 虚拟破坏者与普通破坏者