| Hi,
| >
| I'm having a debug assertion error within the file dbgdel.cpp with the
| expression:
|
| _BLOCK_TYPE_IS_VALID(pHead->nBlockUse)
|
| I traced the origin of the error and it happened as I tried to delete
a
| polymorphic class as follows:
|
| class __declspec(dllexport) A {
| public:
| char* name;
| A( ) { }
| virtual ~A( ) { delete name; }
| }
Deleting a stack allocation is undefined behaviour. That should have
been expected.
class A
{
std::string m_s;
public:
A(std::string s) : m_s(s) { }
virtual ~A() { }
std::string getS() const { return m_s; }
};
|
| class B {
| public:
| B( ) { }
| virtual ~B( ) { }
| }
class B
{
public:
B() { }
virtual ~B() { }
};
|
| class C: public A, public B {
| public:
| C( ) { name = "I am C"; }
| ~C( ) { }
| }
class C : public A, public B
{
public:
C(std::string s) : A(s) { }
~C() { } // virtual
};
|
| int main() {
| B* obj = new C;
| delete B;
| }
the instance created above is not B, it's obj. One does not
allocate/deallocate a type. Types don't exist.
int main()
{
B* obj = new C("a string");
std::string s(obj->getS());
delete obj; // deletes the object at obj, not the pointer
}
Where is all this confusion about types, instances and pointers coming
from? The distinction between a user-type and a variable of this
user-type is *critical* (i can't find a better word).
A drafstman or architect can draw a house on paper as many times as he
likes, he still doesn't have a house. A constructor needs to build the
house using a specific blueprint (a class or struct) before there is a
house to speak of. The house is a variable of that blueprint.
The whole idea about polymorphism is that the instance *at* obj knows
whether its an A, a B or a C. In other words, if you create a container
of pointers and initialize the pointers to valid objects, its the object
pointed_to, not the container, that knows whether its of type B or C.
The appropriate virtual destructor(s) is/are therefore invoked upon
destruction.
int main()
{
std::vector< B* > vpb; // a container of pointers
vpb.push_back( new B );
vpb.push_back( new C("string_2") );
vpb.push_back( new C("string_3") );
for (int i = 0; i < vpb.size(); ++i)
{
delete vpb;
}
// first pass: ~B()
// second pass: ~B() and ~C() are invoked
// third pass: ~B() and ~C() are invoked
// note: at this point you still have a vector of 3 elements.
// The vector doesn't know, nor care, that the 3 pointers
// are now undefined.
} // the vector and its pointers are destroyed here automatically.