Visual C++运行时对象销毁顺序
Visual C++ runtime object destruction order
我偶然发现了一个相当烦人的问题,这个问题与Visual C++运行时在程序退出时销毁我的对象有关。
我有一个类,用于确保对某些状态的引用是有效的。我需要将状态存储一段未知的时间,在这段时间内,状态可能会被破坏,我不能使用shared_ptr
。所以我用
class MyClass
{
private:
static std::list<MyClass*> make_list();
static std::list<MyClass*> refed_list;
static void StateClosed(B* state);
public:
B* state;
MyClass(B* state);
virtual ~MyClass();
bool still_valid() const;
};
MyClass
的每个实例在其构造函数中将自己添加到refed_list
,并在其析构函数中删除自己。如果封装的状态是关闭的,则会通知MyClass
,并检查refed_list
中的封装实例并使其指针无效。这并不是真正相关的,重要的是它使用了static list
,并在构造函数/析构函数中访问该列表。我在定义MyClass
的文件中初始化refed_list
。
现在,问题。。当我的程序关闭时,运行时会在某个时刻清理refed_list
,然后清理MyClass
的实例,调用它们的析构函数。然后,他们尝试访问已经清理过的refed_list
。这导致我的迭代器不正确,并且我得到了未定义的行为,在这种情况下是调试断言失败。
有办法解决这个问题吗?我怀疑我是否可以指定不同编译单元中的哪些顺序对象被销毁,但有没有办法检查refed_list
是否仍然有效?目前,我检查refed_list.size() == 0
是否有效,但它的行为也未定义(我认为?)。
您可以始终使refed_list
成为启动时初始化的指针。那样它就永远不会被清理掉。(当您的进程退出时,操作系统将恢复它使用的任何内存。)
如果这听起来像是解决更深层次设计问题的破解方法,那么它可能是。:)
我不认为这是真的:
当我的程序关闭时,运行时会在某个时刻清理refed_list,然后清理MyClass的实例,调用它们的析构函数。
运行时肯定会清理列表,但不会清理列表中的对象,因为它们是指针。唯一的方法是使用像shared_ptr这样的智能指针类。尽管如此,如果你这样做了,对象会试图在列表被销毁时访问它,我不确定这是未定义的行为,但它肯定看起来不稳定。
也许你应该重新设计它,这样对象就不需要引用存储它们的列表,或者至少在列表被销毁之前(我指的是在list::~list被调用之前)执行。
- CMake-按正确顺序将项目与C运行时对象文件链接
- 具有包含其他对象的类的对象创建顺序
- 按类成员的顺序对包含类对象的C++向量进行排序
- 如果在 C++ 构造函数中以错误的顺序初始化对象数据,会发生什么类型的错误
- QML 对象的销毁顺序
- 构造函数中没有参数的对象类成员按什么顺序初始化?
- 如何更改数组中2个对象的顺序
- 对象指针打印结果以相反的顺序进行
- 在C++中,当表达式涉及对象时,将表达式赋值到对象中时,是否有定义的操作顺序?
- 用QT形式顺序命名的UI对象填充数组
- 如何巩固 Bazel 构建对象的顺序
- 使用相同的文件对象按顺序写入和读取文件
- 共享库中静态对象的销毁顺序
- 当涉及单身对象时,克服静态初始化顺序惨败
- 对同一对象进行评估的链接操作和顺序
- 我可以按任意顺序将对象堆叠在qgraphicsscene中
- 保存对象并以任何特定顺序加载它们
- 返回对象时CTOR/DTOR的顺序
- 如何通过私有字符串变量按字母顺序对对象向量进行排序
- 对象渲染顺序,场景图