deleting this

A

Abhijeet

I was just toying around idea of deleting this from a member function.
Was expecting that any acess to member variable or function after
deleting sould give me dump(segmetation violation).Cause now I am
trying to access freed.
memory.

Is my assumption correct?
I tried following code
---------------------------------------------------
#include <iostream.h>
class A
{
public:
A():_i(0){}
A(int i_):_i(i_){}
void killself(){cout<<"deleting this"<<endl;delete this;A*
test = ((A*)t
his);test=0;_i = 5;}
int getI(){return _i;}
void setI(int i_=0){_i= i_;}
private:
int _i;
};
int main()
{
A a;
a.setI(10);
cout<<a.getI()<<endl;
a.killself();
cout<<a.getI()<<endl;

A* pa = NULL;
pa = new A(10);
cout<<pa->getI()<<endl;
cout<<"pointer value"<<pa<<endl;
pa->killself();
cout<<pa->getI()<<endl;
cout<<"pointer value"<<pa<<endl;
delete pa;
pa = NULL;
return 0;
}
------------------------------------------
As I was expecting msvc6 gave dump at statement "a.killself();".But if
I comment this line I get dump at "delete pa;". I am unable to
understand the behaviour.Can somebody help me understand what's going
on?

I think there was thread on similar topic, but I m unable to locate
it.Would even appreciate if get link for same.

Regards,
Abhijeet
Ps. - If I comiple it with "gcc version 3.3.1 (cygming special)" code
runs perfectly fine without any dump. Same is case with Sun workshop
 
S

Sharad Kala

Abhijeet said:
I was just toying around idea of deleting this from a member function.
Was expecting that any acess to member variable or function after
deleting sould give me dump(segmetation violation).Cause now I am
trying to access freed.
memory.

Is my assumption correct?
I tried following code
Non -standard header.
class A
{
public:
A():_i(0){}
A(int i_):_i(i_){}
void killself(){cout<<"deleting this"<<endl;delete this;A*
test = ((A*)t
his);test=0;_i = 5;}
int getI(){return _i;}
void setI(int i_=0){_i= i_;}
private:
int _i;

Prefer trailing undersores in variable names.
}; [snip]
As I was expecting msvc6 gave dump at statement "a.killself();".But if
I comment this line I get dump at "delete pa;". I am unable to
understand the behaviour.Can somebody help me understand what's going
on?

Anything could occur once you enter the realm of Undefined behavior.
You are lucky to have got a crash with the first killself.
These are the problems with the code
-Trying to delete a variable allocated on stack.
- Trying to write to freed memory (_i = 5)
- Later trying to delete the already freed memory again.
Anyone can be a source of UB.

-Sharad
 
M

Marcin Kalicinski

Uzytkownik "Abhijeet said:
I was just toying around idea of deleting this from a member function.
Was expecting that any acess to member variable or function after
deleting sould give me dump(segmetation violation).Cause now I am
trying to access freed.
memory.

Is my assumption correct?
I tried following code
---------------------------------------------------
#include <iostream.h>
class A
{
public:
A():_i(0){}
A(int i_):_i(i_){}
void killself(){cout<<"deleting this"<<endl;delete this;A*
test = ((A*)this);test=0;_i = 5;}

After you've deleted the object with 'delete this', when you try to access
its data member _i, you get undefined behavior. It means that anything can
happen - nothing, core dump, hard drive reformat etc. Assigining zero to
'test' variable is senseless in the above code - a least it does not modify
'this' pointer (but only its copy), if it is what you wanted to do.
int getI(){return _i;}
void setI(int i_=0){_i= i_;}
private:
int _i;
};
int main()
{
A a;
a.setI(10);
cout<<a.getI()<<endl;
a.killself();
cout<<a.getI()<<endl;

A* pa = NULL;
pa = new A(10);
cout<<pa->getI()<<endl;
cout<<"pointer value"<<pa<<endl;
pa->killself();
cout<<pa->getI()<<endl;
cout<<"pointer value"<<pa<<endl;
delete pa;
pa = NULL;
return 0;
}

Earlier in the program there's undefined behavior when you delete the object
'a' which was created on stack. Most probably it corrupts the heap, that's
why you have coredump at next delete.
I am unable to
understand the behaviour.Can somebody help me understand what's going
on? I think there was thread on similar topic, but I m unable to locate
it.Would even appreciate if get link for same.
Ps. - If I comiple it with "gcc version 3.3.1 (cygming special)" code
runs perfectly fine without any dump. Same is case with Sun workshop

Your program is full of undefined behavior, so I'm not surprised that it
works differently on various compilers.

regards,
Marcin
 
P

Peter van Merkerk

Abhijeet said:
I was just toying around idea of deleting this from a member function.
Was expecting that any acess to member variable or function after
deleting sould give me dump(segmetation violation).Cause now I am
trying to access freed memory.

Is my assumption correct?

No, basically anything can happen, the program even may appear to function
correctly! The reason why the program may be able to continue is that if
you delete something, the memory is not necessarilly released to the OS. It
may still be mapped by the OS, and even the contents may not have changed.
So if you access that memory afterwards, there is nothing wrong with that
as far as the OS is concerned. However since that memory is marked as free,
it may be used by other objects at some point. Very strange things can
happen if you try to do something with the deleted object. These bugs can
be very difficult to trackdown, because the program may crash long after
the point where the problem was caused.
 
K

Karl Heinz Buchegger

Abhijeet said:
I was just toying around idea of deleting this from a member function.
Was expecting that any acess to member variable or function after
deleting sould give me dump(segmetation violation).Cause now I am
trying to access freed.
memory.

Is my assumption correct?

Technically you have brought up what is called: undefined behaviour.
That means: anything is possible. This also includes: seems to
work.

People often have false assumptions about what happens deep
in the internals of memory management.
Typically it is done this way: There is a table which
holds pointers to allocated memory (or the other way
round: memory not used by now). When you do a delete
all that is happening is some bookkeeping to update
those tables and that's it. The memory itself does
not vanish into thin air, it is still there and of
course still holds the content it had before the
delete (memory cells don't magically change their
content). So why do you sometimes get an access
violation? The thing is: memory itself often is
organized in memory pages. A typical memory page
contains eg. 4 KByte of memory. When the C++ memory
manager needs some memory, it asks the operating system
for such a page. The operating system hands out such a page
and marks it as 'belonging to process xxx'. The memory
manager then subdivides that page as needed to fullfill
your programs request. Now whenever you access some memory,
the hardware checks that the page the requested memory cell
is in, really can be accessed by that process. That's it. This
also means, that if your request is in a memory page allocated
to your process but not handed out already by the C++ memory
manager, the hardware is unable to detect this failure. Technically
the page does belong to your process und thus the hardware
has no reason to moan.
When you delete something, then the memory is typically not
immediatly handed back to the operating system. There might
be other memory allocations in the same page and also this would
be time consuming. But only if the C++ memory manager hands back
the page to the OS, the OS is capable of marking that page as:
'does not belong to process xxx' and only then the hardware would
be capable of detecting that access violation.


So now, the question is: Why is all of this done this way. Especially
why are there those pages? And the answer is: For simplicity. It is
literally impossible to build up a whole data structure just to
guard each memory cell. For 128 MByte of memory, you would need at
least another 128 MByte just to hold the access permissions. Thats
surely not economical.
 
B

Brian Rodenborn

Abhijeet said:
I was just toying around idea of deleting this from a member function.
Was expecting that any acess to member variable or function after
deleting sould give me dump(segmetation violation).Cause now I am
trying to access freed.
memory.


This is a pointless exercise. It's not generally possible to determine what
behavior undefined behavior has. Learn proper C++ and leave off the
directionless experimenting with illegal stuff, it tells you nothing.



Brian Rodenborn
 
A

Abhijeet

Thanks for advice,
It wasn't directionless experiment actually.
Had some heated argument with in my previous interviewer trying to
explain that its a undefined behaviour.Bust seems like she was stuck
on segmentation violation thing.
And i suppose this type of code is perfectly valid in some cases.Only
thing I wasn't sure about was when object is on stack.
Got very good explanation from some of guys,So thank you very much.

Regards
Abhijeet
 

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,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top