delete pointer

Y

Yin99

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;
}
 
J

John Ratliff

Yin99 said:
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
 
D

Default User

Yin99 said:
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
 
F

Free Bird

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.
 
A

Andre Kostur

Because you are invoking Undefined Behaviour, which might include looking
like it's working.
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.....
 
G

Greg

Yin99 said:
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
 
G

Girish Shetty

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
 
J

John Ratliff

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
 
G

Girish Shetty

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
 
K

Karl Heinz Buchegger

Girish said:
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.
 
G

Girish Shetty

Karl Heinz Buchegger said:
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
 
K

Karl Heinz Buchegger

Girish said:
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.
 
E

Earl Purple

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.
 

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,755
Messages
2,569,536
Members
45,014
Latest member
BiancaFix3

Latest Threads

Top