Virtual destructor problem

G

GAURAV AGRAWAL

Hi Guys,
Can someone please explain me why this is happening

#include<iostream>
using namespace std;

class a {

public:
int a1; // If I remove this it'll work fine
a() {
cout << "Constructor of a \n";
}
~a() {
cout << "Destructor of a \n";
}

};

class b : public a{

public:
b() {
cout << "constructor of b \n";
}
virtual ~b() { // If I remove virtual from here ... it'll work fine
cout << "destructor of b\n";
}

};

int main() {
a *p = new b;

delete p;

return 0;
}

Result is :
Constructor of a
constructor of b
Destructor of a
a.out(1563) malloc: *** error for object 0x100154: Non-aligned pointer
being freed
*** set a breakpoint in malloc_error_break to debug
----------------------------------------------------------------

I know that if I'll put virtual in front of the destructor of the base
class code will work fine. But, I want to use it the above way. Can
someone please explain me the reason behind this kind of behavior?

Thanks in advance
 
D

dertopper

Hi Guys,
Can someone please explain me why this is happening

#include<iostream>
using namespace std;

class a {

public:
int a1;     // If I remove this it'll work fine
a() {
        cout << "Constructor of a \n";
     }
~a() {
          cout << "Destructor of a \n";
     }

};

class b : public a{

public:
b() {
  cout << "constructor of b \n";}

virtual ~b() {    // If I remove virtual from here ... it'll work fine
  cout << "destructor of b\n";

}
};

int main() {
  a *p = new b;

  delete p;

  return 0;

}

Result is :
Constructor of a
constructor of b
Destructor of a
a.out(1563) malloc: *** error for object 0x100154: Non-aligned pointer
being freed
*** set a breakpoint in malloc_error_break to debug
----------------------------------------------------------------

I know that if I'll put virtual in front of the destructor of the base
class code will work fine. But, I want to use it the above way. Can
someone please explain me the reason behind this kind of behavior?

Let's say it bluntly: You cannot do it the way you want. You _have_ to
make the destructor of the base class virtual, or you'll get in
trouble when you try to delete derived objects through a base class
pointer. I cannot cite the paragraphs of the C++ standard which say
that you have to do it this way, so I'll try to explain it with my own
words: If you were the compiler and should delete a pointer to 'a',
you'll either (A) call a's destructor right away if 'a' is a class
without virtual destructor, or else (B) look up a's virtual method
table to get the address of the most derived destructor (it your case
b's destructor). If 'a' has no virtual destructor, the compiler
doesn't reserve an entry for destructors in a's VMT, even though
derived classes may have virtual destructors (this is a bit of an
optimization, as it may be the case that 'a' is not derived at all).

Regards,
Stuart
 
J

James Kanze

Can someone please explain me why this is happening
#include<iostream>
using namespace std;
class a {
public:
int a1; // If I remove this it'll work fine
a() {
cout << "Constructor of a \n";
}
~a() {
cout << "Destructor of a \n";
}
};
class b : public a{
public:
b() {
cout << "constructor of b \n";
}
virtual ~b() { // If I remove virtual from here ... it'll work fine
cout << "destructor of b\n";
}
};
int main() {
a *p = new b;
delete p;
return 0;
}
Result is :
Constructor of a
constructor of b
Destructor of a
a.out(1563) malloc: *** error for object 0x100154: Non-aligned pointer
being freed
*** set a breakpoint in malloc_error_break to debug
----------------------------------------------------------------
I know that if I'll put virtual in front of the destructor of
the base class code will work fine. But, I want to use it the
above way. Can someone please explain me the reason behind
this kind of behavior?

Simple. It's undefined behavior. So the compiler can assume
that you don't do it, and not take any steps that would
otherwise be necessary for it to work. The standard is very
clear about this: for a non-array delete, either the dynamic
type is the same as the static type, the destructor is virtual,
or you have undefined behavior. (For an array delete, the
dynamic and static types must be the same, period.)
 
S

Sunil Varma

Simple. It's undefined behavior. So the compiler can assume
that you don't do it, and not take any steps that would
otherwise be necessary for it to work. The standard is very
clear about this: for a non-array delete, either the dynamic
type is the same as the static type, the destructor is virtual,
or you have undefined behavior. (For an array delete, the
dynamic and static types must be the same, period.)

--
James Kanze (GABI Software) email:[email protected]
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


The same is the behavior for a virtual method which is not the
destructor.
The process crashes when delete statement is encountered.
I suppose there should be some problem in deleting the extra
memory(the virtual pointer) used by the object of type b with a
pointer of type type a.
 

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,766
Messages
2,569,569
Members
45,042
Latest member
icassiem

Latest Threads

Top