By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
448,616 Members | 1,618 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 448,616 IT Pros & Developers. It's quick & easy.

Virtual destructor problem

P: n/a
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
Jun 27 '08 #1
Share this Question
Share on Google+
3 Replies


P: n/a
On 24 Apr., 07:59, GAURAV AGRAWAL <g...@buffalo.eduwrote:
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
Jun 27 '08 #2

P: n/a
On Apr 24, 7:59 am, GAURAV AGRAWAL <g...@buffalo.eduwrote:
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.)

--
James Kanze (GABI Software) email:ja*********@gmail.com
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
Jun 27 '08 #3

P: n/a
On Apr 24, 4:18 pm, James Kanze <james.ka...@gmail.comwrote:
On Apr 24, 7:59 am, GAURAV AGRAWAL <g...@buffalo.eduwrote:
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.)

--
James Kanze (GABI Software) email:james.ka...@gmail.com
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.
Jun 27 '08 #4

This discussion thread is closed

Replies have been disabled for this discussion.