147

Theoretically I can say that

free(ptr);
free(ptr); 

is a memory corruption since we are freeing the memory which has already been freed.

But what if

free(ptr);
ptr=NULL;
free(ptr); 

As the OS will behave in an undefined manner I cannot get an actual theoretical analysis for this about what's happening. Whatever I am doing, is this memory corruption or not?

Is freeing a NULL pointer valid?

Vijay
  • 65,327
  • 90
  • 227
  • 319
  • 1
    not sure about C free standard, but in C++ delete(NULL) is perfectly valid, so I guess free(NULL) should also be. – Priyank Bolia Dec 21 '09 at 07:47
  • 16
    @Pryank: `delete NULL` is not valid in C++. delete can be applied to null-pointer values of concrete type, but not to `NULL`. `delete (int*) NULL` is legal, but not `delete NULL`. – AnT stands with Russia Dec 21 '09 at 07:53
  • so it means if a pointer is pointing to NULL free does not perform anything.does that mean!!!!!! every time in our coding if want to free a memory can simply replace a free(ptr) with ptr=NULL? – Vijay Dec 21 '09 at 08:04
  • 4
    No. If `ptr` points to memory, and you don't call `free` on it, then the memory will leak. Setting it to `NULL` just loses your handle on the memory, and leaks. If the `ptr` *happens to be `NULL`*, calling `free` is a no-operations. – GManNickG Dec 21 '09 at 08:05
  • 2
    @benjamin: Huh? What made you to conclude that you can replace `free(ptr)` with `ptr = NULL`. No one said anything like that. – AnT stands with Russia Dec 21 '09 at 08:07
  • @benjamin: free does not free the variable passed in, it frees a __block of memory__ previously allocated and referenced by the pointer value in the passed-in value. So, ptr is not being freed, the block pointed to by ptr is being freed. – Heath Hunnicutt Dec 21 '09 at 08:44
  • Duplicate: http://stackoverflow.com/questions/1879550/should-one-really-set-pointers-to-null-after-freeing-them – dmckee --- ex-moderator kitten Dec 21 '09 at 16:51

11 Answers11

261

7.20.3.2 The free function

Synopsis

#include <stdlib.h> 
void free(void *ptr); 

Description

The free function causes the space pointed to by ptr to be deallocated, that is, made available for further allocation. If ptr is a null pointer, no action occurs.

See ISO-IEC 9899.

That being said, when looking at different codebases in the wild, you'll notice people sometimes do:

if (ptr)
  free(ptr);

This is because some C runtimes (I for sure remember it was the case on PalmOS) would crash when freeing a NULL pointer.

But nowadays, I believe it's safe to assume free(NULL) is a nop as per instructed by the standard.

Gregory Pakosz
  • 69,011
  • 20
  • 139
  • 164
  • so it means if a pointer is pointing to NULL free does not perform anything.does that mean!!!!!! every time in our coding if want to free a memory can simply replace a free(ptr) with ptr=NULL? – Vijay Dec 21 '09 at 08:03
  • 36
    No, ptr=NULL is no way a replacement for free(ptr), both are completely different – Prasoon Saurav Dec 21 '09 at 08:05
  • 13
    NO, it means `free(ptr)` where `ptr` is null has no side effects. But in any case, every memory allocated using `malloc()` or `calloc()` must be released afterwards using `free()` – Gregory Pakosz Dec 21 '09 at 08:06
  • 6
    ptr=NULL ensures that even if you accidently call free(ptr) your program won't segfault. – Prasoon Saurav Dec 21 '09 at 08:06
  • 1
    You don't need to ask your question multiple times. Edit your question post and append the information you want. – GManNickG Dec 21 '09 at 08:07
  • 2
    Please note that although the C standard says it is a no-op, that doesn't mean that every C-library handles it like that. I've seen crashes for free(NULL), so it's best to avoid calling the free in the first place. – Derick Jan 24 '13 at 09:43
  • @Derick avoid calling free? How do you free your memory then? – WereWolfBoy Apr 25 '13 at 13:25
  • 8
    @WereWolfBoy he means avoid `free(NULL)` by testing the pointer against `NULL` before calling `free()` – Gregory Pakosz Apr 25 '13 at 13:32
  • 1
    @GregoryPakosz ah, that makes sense. Sorry :D – WereWolfBoy Apr 25 '13 at 13:56
31

All standards compliant versions of the C library treat free(NULL) as a no-op.

That said, at one time there were some versions of free that would crash on free(NULL) which is why you may see some defensive programming techniques recommend:

if (ptr != NULL)
    free(ptr);
R Samuel Klatchko
  • 74,869
  • 16
  • 134
  • 187
  • 10
    -1 [citation needed]. Changing code-style because of some theory of an archaic hearsay implementation is a bad idea. – Tomas Dec 21 '09 at 14:02
  • 48
    @Tomas - I never recommended changing style, I simply explained why you may still see this recommendation in some styles. – R Samuel Klatchko Dec 21 '09 at 17:51
  • 5
    @Tomas 3BSD (http://www.winehq.org/pipermail/wine-patches/2006-October/031544.html) and PalmOS for two (2nd hand for both). – Douglas Leeder Mar 11 '10 at 14:04
  • 8
    @Tomas: the problem was in things like Version 7 Unix. When I was learning, free(xyz) where xyz == NULL was a recipe for instant disaster on the machine where I learned (ICL Perq running PNX, which was based on Version 7 Unix with some System III extras). But I've not code that way for a long time. – Jonathan Leffler Mar 11 '10 at 14:06
  • 2
    Netware crashes on free-ing NULL too... (just debugged a crash on it...) – Calmarius Oct 22 '13 at 10:26
  • 1
    @Calmarius That's why they are discontinued? LOL – Franklin Yu Jan 08 '17 at 18:34
  • *"All standards compliant versions of the C library treat free(NULL) as a no-op"* - Some non-compliant ones also do. For example, glibc lacks the safer string functions from TR-24731, so it non-compliant; but it does allow you to free a `NULL` ptr and treat it like a nop. Drepper personally opposes the safer string functions so glibc will likely never be compliant. – jww Dec 24 '17 at 05:18
  • 2
    Drepper hasn't been in charge of glibc since 2012. However there are many people who agree with him regarding the (lack of) utility of the string functions in TR-24731. Also C11 Annex K (TR-24731) is optional, so glibc is not non-compliant for omitting it. Finally, there are serious proposals to remove Annex K from the next standard; see N1967 submitted to WG14. Requiring free(NULL) to be a no-op was part of the first ANSI C 1989/ISO C 1990 standard so there's _no_ C runtime compliant with _any_ version of the C standard that doesn't support it. – MadScientist Dec 20 '18 at 22:05
  • @jww The bounds-checking interface added in C11 was always an optional feature. The compiler doesn't have to implement it and can still be compliant. Same thing as with the complex numbers lib, the thread lib and so on: they are optional. – Lundin May 23 '22 at 10:12
14

If ptr is NULL, no operation is performed.

says the documentation.

Michael Krelin - hacker
  • 138,757
  • 24
  • 193
  • 173
13

I remember working on PalmOS where free(NULL) crashed.

jlru
  • 261
  • 1
  • 5
  • 4
    Interesting - that makes a second platform (after 3BSD) that crashes. – Douglas Leeder Mar 11 '10 at 14:02
  • 2
    If I remember correctly, on Palm the C Standard Library didn't exist. Instead, there was a mostly unsupported header file that mapped standard library calls through to the Palm OS SDK. Lots of things acted unexpectedly. Crashing on `NULL` was one of the big running differences of the Palm toolbox compared to the standard library. – Steven Fisher Apr 20 '15 at 17:31
  • PalmOS was *freestanding* C implementation and therefore had no obligation to provide the standard C library. Its analogue to `free` (`MemPtrFree`) was not standards compliant, and `free` was aliased to `MemPtrFree` as a (crude) attempt to provide a standard-*like* API. – jamesdlin Dec 30 '20 at 10:36
9
free(ptr);
ptr=NULL;
free(ptr);/*This is perfectly safe */

You can safely delete a NULL pointer. No operation will be performed in that case.In other words free() does nothing on a NULL pointer.

Prasoon Saurav
  • 91,295
  • 49
  • 239
  • 345
8

Recomended usage:

free(ptr);
ptr = NULL;

See:

man free

     The free() function deallocates the memory allocation pointed to by ptr.
     If ptr is a NULL pointer, no operation is performed.

When you set the pointer to NULL after free() you can call free() on it again and no operation will be performed.

stefanB
  • 77,323
  • 27
  • 116
  • 141
  • 3
    That also help to spot segfaults with a debugger. It is evident that segfault at p->do() with p=0 is someone using a freed pointer. Less evident when you see p=0xbfade12 in debugger :) – neuro Mar 11 '10 at 14:20
7

free(NULL) is perfectly legal in C as well as delete (void *)0 and delete[] (void *)0 are legal in C++.

BTW, freeing memory twice usually causes some kind of runtime error, so it does not corrupt anything.

n0rd
  • 11,850
  • 5
  • 35
  • 56
  • 2
    `delete 0` is not legal in C++. `delete` explicitly requires an expression of pointer type. It is legal to apply `delete` to a typed null-pointer value, but not to `0` (and not to `NULL`). – AnT stands with Russia Dec 21 '09 at 07:49
  • 1
    You cannot delete `void*` either :P Which destructors(s) should it run? – GManNickG Dec 21 '09 at 08:00
  • 1
    @GMan: You *can* delete `void *` as long as it is a null-pointer. – AnT stands with Russia Dec 21 '09 at 08:02
  • Ok, fair enough. I forgot we're only dealing specifically with null. – GManNickG Dec 21 '09 at 08:07
  • usually does not corrupt anything, but is not guaranteed to. ASLR makes this rather unlikely, but still not impossible: ```buf1=malloc(X); free(buf1);buf2=malloc(X);free(buf1); ``` - here if you're unlucky, buf2 got the exact same address as buf1, and you accidentally freed buf1 twice, so on the 2nd free of buf1 you actually freed buf2 silently, without casuing any (immidate) error/crash/whatever. (but you'll still probably get a crash next time you try to use buf2 - and this scenario is very unlikely if you're running on ASLR) – hanshenrik Sep 17 '18 at 15:19
4

free(ptr) is save in C if ptr is NULL, however, what most people don't know is that NULL need not be equal to 0. I have a nice old-school example: On the C64, on address 0, there is an IO-Port. If you wrote a program in C accessing this port, you'd need a pointer whose value is 0. The corresponding C library would have to distinguish between 0 and NULL then.

Kind regards.

Azeem
  • 11,148
  • 4
  • 27
  • 40
andi8086
  • 394
  • 2
  • 9
1

not memory corruption, but behavior depends on implementation. By standard, it should be a legal code.

Pavel Radzivilovsky
  • 18,794
  • 5
  • 57
  • 67
0

Although it is safe nowadays, I always use the following macro to free pointers:

#define FREE(ptr)      \ 
{                      \
    if ((ptr) != NULL) \
    {                  \
        free(ptr);     \
        (ptr) = NULL;  \
    }                  \
}
Mark Luko
  • 31
  • 6
-5

ptr is pointing to some memory location, lets say 0x100.

When you free(ptr), basically you are allowing 0x100 to be used by memory manager to be used for other activity or process and in simple words it is deallocation of resources.

When you do ptr=NULL, you are making ptr point to new location(lets not worry about what NULL is). Doing this you lost track of the 0x100 memory data.This is what is memory leak.

So it is not advisable to use ptr=NULL on a valid ptr.

Instead you could do some safe check by using :

if(ptr != NULL) {free(ptr);}

When you free(ptr) where ptr is already pointing to NULL, it performs no operation.So, its safe to do so.

kishanp
  • 1
  • 1
  • But if the memory is already freed as in the question then the pointer is invalid and should be set to `NULL` so if it is freed again there will not be a double free error – user16217248 Oct 16 '21 at 17:22