curious behaviour in virtual destructor inside base class

Discussion in 'C++' started by LAvoisieR, Oct 27, 2005.

  1. LAvoisieR

    LAvoisieR Guest

    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; }
     
    LAvoisieR, Oct 27, 2005
    #1
    1. Advertising

  2. LAvoisieR

    TIT Guest

    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
     
    TIT, Oct 27, 2005
    #2
    1. Advertising

  3. LAvoisieR

    Guest

    LAvoisieR wrote:
    > 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
     
    , Oct 27, 2005
    #3
  4. LAvoisieR

    Neil Cerutti Guest

    On 2005-10-27, LAvoisieR <> wrote:
    > 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.

    --
    Neil Cerutti
     
    Neil Cerutti, Oct 27, 2005
    #4
  5. LAvoisieR

    mlimber Guest

    LAvoisieR wrote:
    > 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
     
    mlimber, Oct 27, 2005
    #5
  6. LAvoisieR wrote:
    > 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
     
    Jonathan Mcdougall, Oct 27, 2005
    #6
  7. wrote:
    > LAvoisieR wrote:
    > > 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.


    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
     
    Jonathan Mcdougall, Oct 27, 2005
    #7
  8. LAvoisieR

    red floyd Guest

    Jonathan Mcdougall wrote:
    > [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!
     
    red floyd, Oct 27, 2005
    #8
  9. LAvoisieR

    LAvoisieR Guest

    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
     
    LAvoisieR, Oct 27, 2005
    #9
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.

Share This Page