curious behaviour in virtual destructor inside base class

L

LAvoisieR

Following test code behaviour suprised me and I dont know what's wrong
with this. I have two overloaded constructors within base class and
virtual destructor implemented. Derived class uses protected
non-parametrized constructor of base class which DOES NOT initialize
private member 'value'. But by calling both destructors virtually,
binary does not complaint about deleting uninitialized pointer. WHY ??
C++ compiler used: G++ 3.4.3 #include <iostream> using namespace std;
class Base { public: Base(int) : value( new int(-14) ) {}
virtual ~Base() { //cout << *value << endl; // throws
SEGFAULT as supposed delete value; // no SEGFAULT
here ?? WHY ?? } protected: /* Constructor overload for
derived classes */ Base() { // does not
initialize 'value' pointer !!! } private: int *value;
}; class Derived : public Base { public: Derived() : Base() {}
virtual ~Derived() {} }; int main() { Base *p =
new Derived; delete p; }
 
T

TIT

LAvoisieR sade:
Following test code behaviour suprised me and I dont know what's wrong
with this. I have two overloaded constructors within base class and
virtual destructor implemented. Derived class uses protected
non-parametrized constructor of base class which DOES NOT initialize
private member 'value'. But by calling both destructors virtually,
binary does not complaint about deleting uninitialized pointer. WHY ??
C++ compiler used: G++ 3.4.3 #include <iostream> using namespace std;
class Base { public: Base(int) : value( new int(-14) ) {}
virtual ~Base() { //cout << *value << endl; // throws
SEGFAULT as supposed delete value; // no SEGFAULT
here ?? WHY ?? } protected: /* Constructor overload for
derived classes */ Base() { // does not
initialize 'value' pointer !!! } private: int *value;
}; class Derived : public Base { public: Derived() : Base() {}
virtual ~Derived() {} }; int main() { Base *p =
new Derived; delete p; }

My Eyes! AAhh!

TIT
 
I

int2str

LAvoisieR said:
Following test code behaviour suprised me and I dont know what's wrong ....
delete value; // no SEGFAULT here ?? WHY ??

Because it's ok to delete a NULL pointer.
It is not ok to dereference it.

Cheers,
Andre
 
N

Neil Cerutti

Following test code behaviour suprised me and I dont know
what's wrong with this. I have two overloaded constructors
within base class and virtual destructor implemented. Derived
class uses protected non-parametrized constructor of base class
which DOES NOT initialize private member 'value'. But by
calling both destructors virtually, binary does not complaint
about deleting uninitialized pointer. WHY ??

I took the liberty of reformatting your code. It can only have
been posted as it was by mistake. Please be more careful.

class Base
{
public:
Base(int) : value( new int(-14) ) {}
virtual ~Base()
{
delete value; /* no SEGFAULT here ?? WHY ?? */
}
protected: /* Constructor overload for derived classes */
Base() { } /* does not initialize 'value' pointer !!! */
private:
int *value;
};

class Derived : public Base
{
public:
Derived() : Base() {}
virtual ~Derived() {}
};

int main()
{
Base *p = new Derived;
delete p;
}

You can't count on getting a SEGFAULT. What happens when you try
to delete an uninitialized pointer is undefined. If you're lucky,
you get a crash of some sort. If you're unlucky, you just corrupt
the free store.
 
M

mlimber

LAvoisieR said:
Following test code behaviour suprised me and I dont know what's wrong
with this. I have two overloaded constructors within base class and
virtual destructor implemented. Derived class uses protected
non-parametrized constructor of base class which DOES NOT initialize
private member 'value'. But by calling both destructors virtually,
binary does not complaint about deleting uninitialized pointer. WHY ??
C++ compiler used: G++ 3.4.3 #include <iostream> using namespace std;
class Base { public: Base(int) : value( new int(-14) ) {}
virtual ~Base() { //cout << *value << endl; // throws
SEGFAULT as supposed delete value; // no SEGFAULT
here ?? WHY ?? } protected: /* Constructor overload for
derived classes */ Base() { // does not
initialize 'value' pointer !!! } private: int *value;
}; class Derived : public Base { public: Derived() : Base() {}
virtual ~Derived() {} }; int main() { Base *p =
new Derived; delete p; }

Here's a sensible version of the code:

#include <iostream>
using namespace std;
class Base
{
public:
Base(int) : value( new int(-14) ) {}

virtual ~Base()
{
//cout << *value << endl; // throws SEGFAULT as supposed

delete value; // no SEGFAULT here ?? WHY ??
}
protected: /* Constructor overload for derived classes */
Base()
{ // does not initialize 'value' pointer !!!
}

private:
int *value;
};

class Derived : public Base
{
public:
Derived() : Base() {}
virtual ~Derived() {}
};

int main()
{
Base *p = new Derived;
delete p;
}

Methinks you just got lucky and that Base::value is 0. Note that it is
not guaranteed to be 0 (or anything else for that matter -- you should
initialize it to 0 in your default constructor). Dereferencing or
deleting an uninitialized pointer is bad bad bad.

Cheers! --M
 
J

Jonathan Mcdougall

LAvoisieR said:
Following test code behaviour suprised me and I dont know what's wrong
with this. I have two overloaded constructors within base class and
virtual destructor implemented. Derived class uses protected
non-parametrized constructor of base class which DOES NOT initialize
private member 'value'. But by calling both destructors virtually,
binary does not complaint about deleting uninitialized pointer. WHY ??
C++ compiler used: G++ 3.4.3

Please! Format your code next time.
#include <iostream>

using namespace std;

class Base
{
public:
Base(int)
: value( new int(-14) )
{
}

virtual ~Base()
{
// cout << *value << endl; // throws SEGFAULT as supposed

No, it's not supposed to "throw SEGFAULT", it's undefined behavior,
which means it could do anything.
delete value; // no SEGFAULT here ?? WHY ??

Because that's still undefined behavior. When I run your code on my
machine, it deletes all my emails while forcing me watch the little
paper clip in microsoft word dancing around.
}

protected:
/* Constructor overload for derived classes */
Base()
{
// does not initialize 'value' pointer !!!

Well, that's a bad idea.
}

private:
int *value;
};

class Derived : public Base
{
public:
Derived() : Base()
{
}

Unecessary:

Derived()
{
}

does the same thing.
virtual ~Derived()
{
}
};

int main()
{
Base *p = new Derived;
delete p;
}


Jonathan
 
J

Jonathan Mcdougall

Because it's ok to delete a NULL pointer.
It is not ok to dereference it.

If you hadn't snip all the code, you would have seen that it was
uninitialized, not null. Therefore, you get undefined behavior no
matter what you do with it, except giving it another value or doing
nothing.


Jonathan
 
R

red floyd

Jonathan said:
[UB example redacted]
>
Because that's still undefined behavior. When I run your code on my
machine, it deletes all my emails while forcing me watch the little
paper clip in microsoft word dancing around.

You, sir, are truly evil. :) I can't get that image out of my mind now!
 
L

LAvoisieR

Thank you all for advices. I am still quite newbie in C++, I know. And
sorry about my mistake while sending message through web site. LaR
 

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

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,535
Members
45,008
Latest member
obedient dusk

Latest Threads

Top