Question

I'm getting a crash (debug assertion failure: invalid CRT heap pointer in VC++ 2008) in static initialization, and I'm not sure I understand why.

I've read all about the static initialization fiasco over at the C++ FAQ, and I thought I had a grasp on it--I don't understand why this is happening, or why it would be a case of the fiasco.

So here's the situation (most non-static members are omitted for the sake of brevity). I have one class, A, defined in A.h:

class A {
public:
    virtual ~A() { }

    virtual void do_something();
};

Then, I have a class, C, which has a nested class, B, which is a subclass of A. C also contains a private static member of type B:

class C {
public:
    void do_the_C_thing();

private:
    class B : public A {
    public:
        virtual void do_something();
    };

    static B my_personal_B;
};

Finally, there's C's implementation file, C.cpp, which contains my_personal_B's storage unit:

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
}

This pattern is repeated for a lot of classes, each having a nested class which inherits from A. This has all been operating flawlessly through several code revisions, but lately the application crashes with this specific error message:

Debug Assertion Failed!

Program:
[redacted].exe
File: f:\dd\vctools\crt_bld\self_x86\crt\src\dbgheap.c
Line: 1511

Expression: _CrtIsValidHeapPointer(pUserData)

If I click to debug, I'm shown the line in C.cpp, where the static member is defined.

This doesn't seem like a static fiasco, because nothing static refers to my_personal_B, neither A nor B have anything but default constructors, and therefore couldn't possibly be referring to some other not-yet-initialized static object. The way I understood the fiasco is that it happened when one static object referred to another not-yet-initialized static object.

Nevertheless, if I change the static member to an initialize-on-first-use method, the crash seems to go away.

So the question is, why is this crashing?

Was it helpful?

Solution

Class A has virtual functions. What that means is that the compiler produces a static object called a vtable to hold pointers to member functions. So although you did not define any static objects in class A, the compiler must do so. Class B depends on that vtable (for A's virtual destructor, if nothing else). Apparently the initialization code is now trying to create an object of type B before A's vtable is constructed.

OTHER TIPS

Dude, why are you relying on static initialization in the first place? Can you say "design error"?

SUGGESTION:

If you can't change the design, at least be sure to set a flag "bInitialized" so dependent clients can check whether or not your object has actually be initialized, and fail gracefully.

IMHO...

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top