【发布时间】:2012-09-28 20:05:28
【问题描述】:
我在静态初始化中遇到了崩溃(调试断言失败:VC++ 2008 中的 CRT 堆指针无效),我不确定我是否理解原因。
我已经在 C++ FAQ 上阅读了有关 static initialization fiasco 的所有内容,我想我已经掌握了它——我不明白为什么会发生这种情况,或者为什么会出现这种情况惨败。
这就是这种情况(为了简洁起见,大多数非静态成员都被省略了)。我有一个类,A,在 A.h 中定义:
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 除了默认构造函数之外都没有任何东西,因此不可能引用其他尚未初始化的静态对象。我理解惨败的方式是,当一个静态对象引用另一个尚未初始化的静态对象时,它就发生了。
不过,如果我将静态成员更改为首次使用时初始化的方法,崩溃似乎就消失了。
所以问题是,为什么会崩溃?
【问题讨论】:
-
1.什么时候崩溃? 2.什么是调用栈?
标签: visual-studio-2008 visual-c++ static-initialization