Deleting a Polymorphic Class

F

FefeOxy

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; }
}

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

class C: public A, public B {
public:
C( ) { name = "I am C"; }
~C( ) { }
}

int main() {
B* obj = new C;
delete B;
}


This is done in VC 7.1. Can anyone help me solve my problem?
 
J

Jim Langston

FefeOxy said:
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; }
}

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

class C: public A, public B {
public:
C( ) { name = "I am C"; }
~C( ) { }
}

If this is the actual code, name = "I am C", then you are changing where the
pointer is pointing to, and it's not being allocated with new. You only use
delete if the memory was allocated with new, which wasn't in this case.
Which would definately be the cause of your error.
 
A

Alf P. Steinbach

* FefeOxy:
class __declspec(dllexport) A {
public:
char* name;
A( ) { }
virtual ~A( ) { delete name; }
}

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

class C: public A, public B {
public:
C( ) { name = "I am C"; }
~C( ) { }
}

int main() {
B* obj = new C;
delete B;
}


This is done in VC 7.1. Can anyone help me solve my problem?

First, "__declspec(dllexport)" is not relevant and is not standard C++,
and you're missing a bunch of semicolons: this code won't compile.

At the very lowest technical level: you're trying to 'delete' something
that wasn't allocated by 'new'.

At a slightly higher level, you have a very confused or no intentional
allocation of responsibilities. Be clear about responsibilities, choose
what is responsible for that, and design that in. Also, make sure to
initialize things, which you have forgotten above: there should never
exist an uninitialized or partially uninitialized object anywhere.

Hth.,

- Alf
 
F

FefeOxy

Thank you for your help. Is there a more relevent newsgroup that I
should be going to?
 
A

Alf P. Steinbach

* FefeOxy:
Thank you for your help. Is there a more relevent newsgroup that I
should be going to?

No, this one's fine for C++ issues.

I hope you got that about 'delete' requiring allocation by 'new' (or
nullpointer).

Cheers,

- Alf
 
P

Peter_Julian

| 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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,996
Messages
2,570,238
Members
46,826
Latest member
robinsontor

Latest Threads

Top