36

For example:

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

Are there any adverse side effects of doing this?

lillq
  • 14,758
  • 20
  • 53
  • 58

14 Answers14

41

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
  • 55,321
  • 43
  • 129
  • 155
20

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

mbac32768
  • 11,453
  • 9
  • 34
  • 40
14

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.

jbleners
  • 1,023
  • 1
  • 8
  • 14
9

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

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
lillq
  • 14,758
  • 20
  • 53
  • 58
6

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

Armin Ronacher
  • 31,998
  • 13
  • 65
  • 69
  • 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. – jbleners Sep 25 '08 at 19:40
  • ajbl, use a macro. #define freep(x) (free(x); x = 0;) – Derek Park Sep 25 '08 at 19:46
  • Bad idea, since it's not applicable to const values. You do use const values where possible, don't you? – Steve Jessop Nov 30 '08 at 14:47
  • @Steve: I know this is old, but didn't we elsewhere discuss that passing a const-qualified pointer to `free` is not valid (both conceptually and formally, unless you cast away the qualifier)? :-) – R.. GitHub STOP HELPING ICE Sep 06 '11 at 04:05
  • @R..: I'm talking about `char *const ptr = malloc(STRING_BUFFER_SIZE); ... ; free(ptr);`. I don't think that is either formally or conceptually invalid. After that, `ptr = 0;` isn't on the cards. So if you define a macro `freep` as Derek says, then you can't use it on `ptr`. – Steve Jessop Sep 06 '11 at 07:22
6

It (potentially) makes demons fly out of your nose.

Jens
  • 69,818
  • 15
  • 125
  • 179
5

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
  • 197,344
  • 39
  • 212
  • 226
3

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.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Martin Beckett
  • 94,801
  • 28
  • 188
  • 263
3

Bad Things (TM)

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

BCS
  • 75,627
  • 68
  • 187
  • 294
2

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
  • 13,068
  • 3
  • 28
  • 27
1

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
  • 36,103
  • 8
  • 58
  • 81
1

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
  • 47,778
  • 10
  • 99
  • 143
1

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
  • 11,453
  • 9
  • 34
  • 40
-1

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
  • 505
  • 5
  • 19