我在静态初始化中遇到崩溃(调试断言失败:VC++ 2008 中的无效 CRT 堆指针),我不确定我是否理解原因。
我已经阅读了C++ FAQ中有关静态初始化惨败的所有内容,并且我想我已经掌握了它——我不明白为什么会发生这种情况,或者为什么会出现这种惨败。
这就是这种情况(为简洁起见,省略了大多数非静态成员)。我有一个类 A,在 Ah 中定义:
class A {
public:
virtual ~A() { }
virtual void do_something();
};
然后,我有一个类 C,它有一个嵌套类 B,它是 A 的子类。C 还包含 B 类型的私有静态成员:
class C {
public:
void do_the_C_thing();
private:
class B : public A {
public:
virtual void do_something();
};
static B my_personal_B;
};
最后是 C 的实现文件 C.cpp,其中包含 my_personal_B 的存储单元:
C::B my_personal_B;
C::C() {
}
C::do_the_C_thing() {
// [...]
my_personal_B.do_something();
// [...]
}
void C::B::do_something() {
// overridden do_something for C's private B class
}
许多类都重复这种模式,每个类都有一个继承自 A 的嵌套类。通过多次代码修订,这一切都运行得完美无缺,但最近应用程序因以下特定错误消息而崩溃:
调试断言失败!
程序:
[已编辑].exe
文件:f:\dd\vctools\crt_bld\self_x86\crt\src\dbgheap.c
行:1511
表达式:_CrtIsValidHeapPointer(pUserData)
如果单击进行调试,则会在 C.cpp 中显示定义静态成员的行。
这看起来不像是静态惨败,因为没有任何静态引用 my_personal_B,A 和 B 除了默认构造函数之外都没有任何东西,因此不可能引用其他尚未初始化的静态对象。我理解惨败的方式是,当一个静态对象引用另一个尚未初始化的静态对象时,它就发生了。
不过,如果我将静态成员更改为首次使用时初始化的方法,崩溃似乎就消失了。
所以问题是,为什么会崩溃?