可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I thought that the delete command would free up memory I allocated. Can someone explain why it seems I still have the memory in use after delete?
class Test
{
public:
int time;
};
int main()
{
Test *e;
e = new Test;
e->time = 1;
cout << e->time << endl;
delete e;
e->time = 2;
cout << e->time << endl;
return(0);
}
I expected a seg-fault after e->time = 2;
Thanks!
回答1:
When you "delete" memory, you are basically returning the allocated memory back to the heap. This just means that the data structure used to organize heap memory is updated to indicate that the memory is now available to use. It is not cleared out or anything like that. You are accessing memory that still exists, but belongs to the operating system at this point. This is undefined behavior.
EDIT:
And by the way, a seg fault occurs when you try to read memory from a segment that you do not have read permissions for. In a flat memory model this probably means you tried to read memory in kernel space; probably because you dereferenced a bad pointer.
回答2:
I expected a seg-fault after e->time = 2;
You shouldn't "expect" anything to happen; you are invoking undefined behavior, which by definition is, well, undefined. That means that you can no longer make any reasonable expectations about the state of your program.
回答3:
Undefined behavior is just that, undefined. It can even work if it so pleases.
回答4:
Accessing deleted object is an undefined behavior. Anything can happen
回答5:
Dereferencing a pointer to an object that has been deleted is undefined. The memory for that object probably hasn't been overwritten yet so your object is still there (If it works at all).
回答6:
Pointers are a container for an address in memory. You can always use a declared pointer, but unless it's initialized to memory that you own, expect confusion and worse.
Test *e;
e->time = 2;
also compiles and won't work. Minimize this type of confusion so:
{
boost::scoped_ptr<Test> e(new Test);
e->time = 1;
cout << e->time << endl;
e->time = 2;
cout << e->time << endl;
}
No new/delete
needed, just enclosing braces to define the scope, and an appropriate smart pointer.
回答7:
run it under valgrind. it will tell you that you did a bad thing
回答8:
As others have said, what you've done is wrong, but you can't expect any particular behavior.
What's probably happening on most modern systems is the memory allocated for and occupied by e
is on a memory page mapped as valid for your program, and the fact that you have delete
d e
, doesn't not undo that mapping.
So you are still accessing memory that your application has permission to use from OS. Thus, no segmentation fault. It is possible, however that if enough things happen between delete e
and accessing that memory the page will have been remapped. Then you get a seg fault.
回答9:
The reason that doesn't break in your tests is a combination of luck and the fact that you have a very simple, very short routine. You're addressing memory still in your process' space and you have so few instructions, the routine probably runs in one shot.
The delete
keyword de-allocates the memory in the process' memory manager, but it doesn't clear it out or (usually) touch it much at all. If the memory is later used, the values will change, but until then, whatever you last set it to will stick around (more or less, this is undefined after all).
Considering the fact your routine has only a few instructions, chances are high that the processor is executing them sequentially, without changing to another process in between. This has the side effect that nothing else is likely to overwrite your memory or allocate it, so the memory remains in the process' space.
Because it is used again so quickly, the values you left are (likely to be) still there and it is unlikely to be in use by another process.