delete pointer

Discussion in 'C++' started by Yin99, Aug 5, 2005.

  1. Yin99

    Yin99 Guest

    Why am I still able to use this object even though I have deleted it?

    The Output I get is:
    Cat Constructs
    Cat De-structs //deleteing object
    Cat Eats. //My question- why does object still work?

    Thanks
    yin99

    ----- BEGIN CODE SAMPLE ---------------
    #include <iostream>
    using namespace std;
    class Cat
    {
    public:
    void sleep() { cout << "\n Cat sleeps! \n "; }
    speak() { cout << "\n MEOW! \n "; }
    Cat() { cout << "\n Cat Constructs \n" ; }
    ~Cat() { cout << "\n Cat De-structs \n" ; }
    void eat() { cout << "\n Cat Eats.\n" ;}
    private:
    };

    int main ()
    {
    Cat *pearl = new Cat();
    delete pearl;
    pearl->eat(); //Works!
    return 0;
    }
     
    Yin99, Aug 5, 2005
    #1
    1. Advertising

  2. Yin99

    John Ratliff Guest

    Yin99 wrote:
    > Why am I still able to use this object even though I have deleted it?
    >
    > The Output I get is:
    > Cat Constructs
    > Cat De-structs //deleteing object
    > Cat Eats. //My question- why does object still work?
    >
    > Thanks
    > yin99
    >
    > ----- BEGIN CODE SAMPLE ---------------
    > #include <iostream>
    > using namespace std;
    > class Cat
    > {
    > public:
    > void sleep() { cout << "\n Cat sleeps! \n "; }
    > speak() { cout << "\n MEOW! \n "; }
    > Cat() { cout << "\n Cat Constructs \n" ; }
    > ~Cat() { cout << "\n Cat De-structs \n" ; }
    > void eat() { cout << "\n Cat Eats.\n" ;}
    > private:
    > };
    >
    > int main ()
    > {
    > Cat *pearl = new Cat();
    > delete pearl;
    > pearl->eat(); //Works!
    > return 0;
    > }
    >


    Seeing as how no memory was allocated after that, and you didn't erase
    the pointer, it was simply still a valid object.

    Delete doesn't destroy the object. Even if you had allocated memory in
    your object that was deleted, it might still work.

    Note that this behaviour is NOT guaranteed and would NOT work with a
    more complicated program.

    Also, your Cat *pearl = new Cat(); line should be Cat *pearl = new Cat;
    No () are used if there are 0 parameters to the constructor.

    --John Ratliff
     
    John Ratliff, Aug 5, 2005
    #2
    1. Advertising

  3. Yin99

    Default User Guest

    Yin99 wrote:

    >
    > Why am I still able to use this object even though I have deleted it?



    You have performed Undefined Behavior. The Standard doesn't specify
    what will happen. One possible outcome is that it will seem to work at
    first. You may also be trashing the free store and will get an
    unexplained error later.

    Messing around like this teaches you very little about the language,
    and is generally not useful for beginners.




    Brian
     
    Default User, Aug 5, 2005
    #3
  4. Yin99

    Free Bird Guest

    > Why am I still able to use this object even though I have deleted it?
    Because you invoked undefined behavior, which essentially means anything can
    happen.
     
    Free Bird, Aug 5, 2005
    #4
  5. Yin99

    Andre Kostur Guest

    John Ratliff <> wrote in news:0rRIe.224666$x96.217442
    @attbi_s72:

    > Yin99 wrote:
    >> Why am I still able to use this object even though I have deleted it?


    Because you are invoking Undefined Behaviour, which might include looking
    like it's working.

    >> The Output I get is:
    >> Cat Constructs
    >> Cat De-structs //deleteing object
    >> Cat Eats. //My question- why does object still work?
    >>
    >> Thanks
    >> yin99
    >>
    >> ----- BEGIN CODE SAMPLE ---------------
    >> #include <iostream>
    >> using namespace std;
    >> class Cat
    >> {
    >> public:
    >> void sleep() { cout << "\n Cat sleeps! \n "; }
    >> speak() { cout << "\n MEOW! \n "; }
    >> Cat() { cout << "\n Cat Constructs \n" ; }
    >> ~Cat() { cout << "\n Cat De-structs \n" ; }
    >> void eat() { cout << "\n Cat Eats.\n" ;}
    >> private:
    >> };
    >>
    >> int main ()
    >> {
    >> Cat *pearl = new Cat();
    >> delete pearl;
    >> pearl->eat(); //Works!
    >> return 0;
    >> }
    >>

    >
    > Seeing as how no memory was allocated after that, and you didn't erase
    > the pointer, it was simply still a valid object.


    No, it's not a valid object. After you call delete on a pointer, what it
    points to is indeterminate. Dereferencing the pointer at all is
    Undefined Behaviour.

    > Delete doesn't destroy the object. Even if you had allocated memory in
    > your object that was deleted, it might still work.


    Yes, it destroys the object. What happens to the physical memory of
    where that pointer pointed to is undefined.

    > Note that this behaviour is NOT guaranteed and would NOT work with a
    > more complicated program.


    After all, the C++ runtime is within its rights to do a memset(ptr, 0,
    sizeof(*ptr)) during the call to delete.....
     
    Andre Kostur, Aug 5, 2005
    #5
  6. Yin99

    Greg Guest

    Yin99 wrote:
    > Why am I still able to use this object even though I have deleted it?
    >
    > The Output I get is:
    > Cat Constructs
    > Cat De-structs //deleteing object
    > Cat Eats. //My question- why does object still work?
    >
    > Thanks
    > yin99
    >
    > ----- BEGIN CODE SAMPLE ---------------
    > #include <iostream>
    > using namespace std;
    > class Cat
    > {
    > public:
    > void sleep() { cout << "\n Cat sleeps! \n "; }
    > speak() { cout << "\n MEOW! \n "; }
    > Cat() { cout << "\n Cat Constructs \n" ; }
    > ~Cat() { cout << "\n Cat De-structs \n" ; }
    > void eat() { cout << "\n Cat Eats.\n" ;}
    > private:
    > };
    >
    > int main ()
    > {
    > Cat *pearl = new Cat();
    > delete pearl;
    > pearl->eat(); //Works!
    > return 0;
    > }


    Calling a member function of a deleted object usually does crash. The
    only reason why this code may not crash is because the memory pointed
    to by the deallocated pearl pointer is not subsequently accessed -
    either to make the call to eat() or in the implementation of eat()
    itself. If eat() were a virtual function or if eat() referenced a data
    member of Cat then the deallocated memory would be accessed and a crash
    would be much more likely.

    Even though this the code may not crash, it is just as incorrect as if
    it did. In some ways, not crashing is worse since it allows the error
    to go undetected and then show up at the worst possible time.

    Greg
     
    Greg, Aug 6, 2005
    #6

  7. > Why am I still able to use this object even though I have deleted it?
    > The Output I get is:
    > Cat Constructs
    > Cat De-structs //deleteing object
    > Cat Eats. //My question- why does object still work?
    > void eat() { cout << "\n Cat Eats.\n" ;}
    > int main ()
    > {
    > Cat *pearl = new Cat();
    > delete pearl;
    > pearl->eat(); //Works!
    > return 0;
    > }
    >


    Its because of your code!.
    Here in your case, you are not accessing any data member of your class in
    your functiion void Cat::eat()
    So, it does not make any difference whether you have valid pointer !!

    It will work even in this case.

    Cat* pearl;
    pearl->eat(); // It works, becase u r not accessing class specific data (
    Not using state of class).
    So, this point ( which will be passed as the parameter to this function by
    the comipler generated code, is not been used)

    Let me give an example:

    class Sample {

    public :
    Sample(int aVal = 10) : iVal(aVal) { }
    void Display() { cout<<"Sample::Display"<<endl; }
    void DisplayVal() { cout<<"Sample::Display : iVal is "<<iVal<<endl; }

    private:
    int iVal;
    };


    int main () {
    Sample* pSam;
    pSam->Display(); // It works
    pSam->DisplayVal(); // It will CRASH because, I am accessing my class
    state ( data member iVal through this pointer which is not valid)
    }

    Regards
    Girish
     
    Girish Shetty, Aug 8, 2005
    #7
  8. Yin99

    John Ratliff Guest

    > Its because of your code!.
    > Here in your case, you are not accessing any data member of your class in
    > your functiion void Cat::eat()
    > So, it does not make any difference whether you have valid pointer !!
    >
    > It will work even in this case.
    >
    > Cat* pearl;
    > pearl->eat(); // It works, becase u r not accessing class specific data (
    > Not using state of class).
    > So, this point ( which will be passed as the parameter to this function by
    > the comipler generated code, is not been used)
    >


    Is this well-defined behaviour, or an implementation detail?

    Does this mean this would also work?

    Cat *pearl = NULL;
    pearl->eat();

    --John Ratliff
     
    John Ratliff, Aug 9, 2005
    #8
  9. > Is this well-defined behaviour, or an implementation detail?
    >
    > Does this mean this would also work?
    >
    > Cat *pearl = NULL;
    > pearl->eat();


    Yeah.. even this will work.
    As of my knowledge, its well defined behavior, because, the c code for above
    two lines of code will be something like this:

    Cat *pearl = NULL;
    cat_eat(pearl) // See we are passing pearl pointer to the function
    cat_eat.

    and the defination of cat_eat will be like this:

    void cat_eat(cat* this) {
    cout << "\n Cat Eats.\n" ;
    }

    And in this function, we are not using this pointer (cat* this). Its very
    obvious that, it will fail / CRASH, if in case u were using this pointer to
    access any of the member of that class, which u were not doing.

    Regards
    Girish
     
    Girish Shetty, Aug 9, 2005
    #9
  10. Girish Shetty wrote:
    >
    > > Is this well-defined behaviour, or an implementation detail?
    > >
    > > Does this mean this would also work?
    > >
    > > Cat *pearl = NULL;
    > > pearl->eat();

    >
    > Yeah.. even this will work.
    > As of my knowledge, its well defined behavior, because, the c code for above
    > two lines of code will be something like this:
    >
    > Cat *pearl = NULL;
    > cat_eat(pearl) // See we are passing pearl pointer to the function
    > cat_eat.
    >
    > and the defination of cat_eat will be like this:
    >
    > void cat_eat(cat* this) {
    > cout << "\n Cat Eats.\n" ;
    > }
    >
    > And in this function, we are not using this pointer (cat* this). Its very
    > obvious that, it will fail / CRASH, if in case u were using this pointer to
    > access any of the member of that class, which u were not doing.


    Man.
    Don't guess but learn how the language works.
    You are walking on thin ice here. In fact all of the above has undefined
    behaviour. It may work or it may not work. Who knows, it is undefined.

    Read it from my lips, aeh, keystrokes:
    dereferencing an pointer with a 0 value is undefined. It doesn't matter
    that the compiler optimizes the dereference away under the hood. In the
    source code

    pearl->eat()

    you dereference a 0 pointer -> undefined behaviour. Period.

    --
    Karl Heinz Buchegger
     
    Karl Heinz Buchegger, Aug 9, 2005
    #10
  11. "Karl Heinz Buchegger" <> wrote in message
    news:...
    > Girish Shetty wrote:
    > >
    > > > Is this well-defined behaviour, or an implementation detail?
    > > >
    > > > Does this mean this would also work?
    > > >
    > > > Cat *pearl = NULL;
    > > > pearl->eat();

    > >
    > > Yeah.. even this will work.
    > > As of my knowledge, its well defined behavior, because, the c code for

    above
    > > two lines of code will be something like this:
    > >
    > > Cat *pearl = NULL;
    > > cat_eat(pearl) // See we are passing pearl pointer to the function
    > > cat_eat.
    > >
    > > and the defination of cat_eat will be like this:
    > >
    > > void cat_eat(cat* this) {
    > > cout << "\n Cat Eats.\n" ;
    > > }
    > >
    > > And in this function, we are not using this pointer (cat* this). Its

    very
    > > obvious that, it will fail / CRASH, if in case u were using this pointer

    to
    > > access any of the member of that class, which u were not doing.

    >
    > Man.
    > Don't guess but learn how the language works.
    > You are walking on thin ice here. In fact all of the above has undefined
    > behaviour. It may work or it may not work. Who knows, it is undefined.
    >
    > Read it from my lips, aeh, keystrokes:
    > dereferencing an pointer with a 0 value is undefined. It doesn't matter
    > that the compiler optimizes the dereference away under the hood. In the
    > source code
    >
    > pearl->eat()
    >
    > you dereference a 0 pointer -> undefined behaviour. Period.
    >
    > --


    When you are not going to use a pointer in your function, does it make any
    difference whether you have something valid or NULL or what soever it
    is????????

    Regards
    Girish


    > Karl Heinz Buchegger
    >
     
    Girish Shetty, Aug 10, 2005
    #11
  12. Girish Shetty wrote:
    >
    >
    > When you are not going to use a pointer in your function, does it make any
    > difference whether you have something valid or NULL or what soever it
    > is????????


    It is completely irrelevant what the function does or what it does not.
    It is the *call* that gives undefined behaviour.

    You are not allowed to dereference a 0 pointer. Something you
    undoubtly do when you do:

    pearl->eat();

    It doesn't matter that the compiler is able to optimize that in a way
    such that the actual pointer value is not needed for making the call.
    In the source code there is a dereference operation, and that gives
    undefined behaviour if that pointer has a 0 value.

    --
    Karl Heinz Buchegger
     
    Karl Heinz Buchegger, Aug 10, 2005
    #12
  13. Yin99

    Earl Purple Guest

    It will probably work with most compilers as the compiler is unlikely
    to do dereference the pointer at all - in fact the function is likely
    to be inlined.
    Not advisable to code in this manner though.
     
    Earl Purple, Aug 10, 2005
    #13
    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.
Similar Threads
  1. Replies:
    10
    Views:
    741
    Chris Torek
    Feb 4, 2005
  2. jimjim
    Replies:
    16
    Views:
    874
    Jordan Abel
    Mar 28, 2006
  3. morz
    Replies:
    7
    Views:
    465
    Marco Wahl
    Feb 6, 2006
  4. Replies:
    4
    Views:
    1,325
    Fred Zwarts
    Jul 2, 2009
  5. A
    Replies:
    7
    Views:
    656
Loading...

Share This Page