Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dereferencing deleted pointers always result in an Access Violation?

I have a very simple C++ code here:

char *s = new char[100];
strcpy(s, "HELLO");
delete [] s;
int n = strlen(s);

If I run this code from Visual C++ 2008 by pressing F5 (Start Debugging,) this always result in crash (Access Violation.) However, starting this executable outside the IDE, or using the IDE's Ctrl+F5 (Start without Debugging) doesn't result in any crash. What could be the difference?

I also want to know if it's possible to stably reproduce the Access Violation crash caused from accessing deleted area? Is this kind of crash rare in real-life?

like image 507
Gant Avatar asked May 24 '10 10:05

Gant


People also ask

What happens when a pointer is deleted tree?

Deleting the pointer won't set it to NULL, it deletes the memory pointed to by the pointer. Even if you were to examine the memory you won't be able to make out whether it's free or not.

What happens in Dereferencing?

Dereferencing is used to access or manipulate data contained in memory location pointed to by a pointer. *(asterisk) is used with pointer variable when dereferencing the pointer variable, it refers to variable being pointed, so this is called dereferencing of pointers.

Do all pointers need to be deleted?

You don't need to delete it, and, moreover, you shouldn't delete it. If earth is an automatic object, it will be freed automatically. So by manually deleting a pointer to it, you go into undefined behavior. Only delete what you allocate with new .

Can you reassign a deleted pointer?

Yes it is safe. It's useless to set the deleted pointer to NULL if you're about to reassign it anyway. The reason people set deleted pointers to NULL is so they can "mark" it as deleted, so later they can check if it has already been deleted.


2 Answers

The difference is that a debugger, and debug libraries, and code built in "debug" mode, likes to break stuff that should break. Your code should break (because it accesses memory it no longer technically owns), so it breaks easier when compiled for debugging and run in the debugger.

In real life, you don't generally get such unsubtle notice. All that stuff that makes things break when they should in the debugger...that stuff's expensive. So it's not checked as strictly in release. You might be able 99 times out of 100 to get away with freeing some memory and accessing it right after, cause the runtime libs don't always hand the memory back to the OS right away. But that 100th time, either the memory's gone, or another thread owns it now and you're getting the length of a string that's no longer a string, but a 252462649-byte array of crap that runs headlong into unallocated (and thus non-existent, as far as you or the runtime should care) memory. And there's next to nothing to tell you what just happened.

So don't do that. Once you've deleted something, consider it dead and gone. Or you'll be wasting half your life tracking down heisenbugs.

like image 199
cHao Avatar answered Oct 10 '22 00:10

cHao


Accessing memory through a deleted pointer is undefined behavior. You can't expect any reliable/repeatable behavior.

Most likely it "works" in the one case because the string is still "sitting there" in the now available memory -= but you cannot rely on that. VS fills memory with debug values to help force crashes to help find these errors.

like image 23
Steve Fallows Avatar answered Oct 10 '22 00:10

Steve Fallows