views:

1375

answers:

14

For example:

char * myString = malloc(sizeof(char)*STRING_BUFFER_SIZE);
free(myString);
free(myString);

Are there any adverse side effects of doing this?

+13  A: 

Yes, you can get a double free error that causes your program to crash. It has to do with malloc's internal data structures to keep track of allocated memory.

ajbl
+3  A: 

Depending on which system you run it on, nothing will happen, the program will crash, memory will be corrupted, or any other number of interesting effects.

John Millikin
+2  A: 

Don't do that. If the memory that got freed is re-allocated to something else between the calls to free, then things will get messed up.

Khoth
Things will usually be messed up even if the memory is not reallocated between the two calls to free.
Jonathan Leffler
+16  A: 

One of nothing, silent memory corruption, or segmentation fault.

mbac32768
hrm, where did you pull this from?i get double free errors...
Matt Joiner
+4  A: 

Not so clever. Google for double free vulnerabilities. Set your pointer to NULL after freeing to avoid such bugs.

Armin Ronacher
Unfortunately you can't write a wrapper to free that does this for you, the pointer is passed by value not reference. i.e. Free(void **p) {free(*p); *p = NULL;} This is not as easy to retool code with.
ajbl
ajbl, use a macro.#define freep(x) (free(x); x = 0;)
Derek Park
Bad idea, since it's not applicable to const values. You do use const values where possible, don't you?
Steve Jessop
+2  A: 

Always set a pointer to NULL after freeing it. It is safe to attempt to free a null pointer.

It's worth writing your own free wrapper to do this automatically.

Martin Beckett
Your free() wrapper must either be a macro or must use a different interface from the standard free() function.
Jonathan Leffler
+2  A: 

Bad Things (TM)

Really, I think it's undefined so anything at all including playing "Global Thermonuclear War" with NORAD's mainframe

BCS
+1  A: 

It may crash your program, corrupt memory, or have other more subtle negative effects. After you delete memory, it is a good idea to set it to NULL (0). Trying to free a null pointer does nothing, and is guaranteed to be safe. The same holds true for delete in c++.

luke
+4  A: 

Answer summary:

Yes, bad things can and probably will happen.

To prevent this do:

free(myString);
myString = NULL;

Note that all references to the memory must be set to NULL if others were created.

Also, calling free() with a NULL results in no action. For more info see: man free

lillq
Note that if you have made any copies of the pointer those should be set to NULL as well.
Michael Carman
Added an edit to address your comment.
lillq
Seems like the community is leaning more towards putting answer summaries in the actual question, not as a question that is still buried...
PhirePhly
Bad idea, since it's not applicable to const values. You do use const values where possible, don't you?
Steve Jessop
+1  A: 

In short: "Undefined Behavior".

(Now, what that can include and why that is the case the others have already said. I just though it was worth mentioning the term here as it is quite common).

Christian.K
Google for 'nasal demons' to find out more.
Jonathan Leffler
+12  A: 

Here's the chapter and verse.

If the argument [to the free function] does not match a pointer earlier returned by the calloc, malloc, or realloc function, or if the space has been deallocated by a call to free or realloc, the behavior is undefined. (ISO 9899:1999 - Programming languages — C, Section 7.20.3.2)

Chris Conway
FYI: When C or C++ say "undefined" they usually mean "crash" or "memory corruption" or something equally terrible. Beware.
Orion Edwards
No, they really do mean "undefined." That just happens to include crashes and memory corruption.
Chris Conway
+1  A: 

The admittedly strange macro below is a useful drop-in replacement for wiping out a few classes of security vulnerabilities as well as aid debugging since accesses to free()'d regions are more likely to segfault instead of silently corrupting memory.

#define my_free(x) do { free(x); x = NULL; } while (0)

The do-while loop is to help surrounding code more easily digest the multiple-statements. e.g. if (done) my_free(x);

mbac32768
Wouldn't "#define my_free(x) { free(x); x = NULL; }" work just as well?
Graeme Perrow
No, after expansion there's an illegal semicolon in if (done) {free(x); x=NULL}; else do_more();Good luck finding the "else without matching if" error in your original source.
MSalters
A: 

Another interesting situation:

char * myString = malloc(sizeof(char)*STRING_BUFFER_SIZE);
char * yourString = myString;

if (myString)
{
    free(myString);
    myString = NULL;
}
// Now this one is safe, because we keep to the rule for 
// setting pointers to NULL after deletion ...
if (myString)
{
    free(myString);
    myString = NULL;
}

// But what about this one:
if (yourString)
{
    free(yourString);
    yourString = NULL;
}

//?!? :)
pinpinokio
A: 

It depends on the c library. ;-)

nicomen