Does free(ptr) where ptr is NULL corrupt memory?

95,306

Solution 1

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.

Solution 2

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);

Solution 3

If ptr is NULL, no operation is performed.

says the documentation.

Solution 4

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

Solution 5

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.

Share:
95,306
Vijay
Author by

Vijay

http://theunixshell.blogspot.com/

Updated on May 05, 2020

Comments

  • Vijay
    Vijay about 4 years

    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?

    • J.Joe
      J.Joe over 14 years
      not sure about C free standard, but in C++ delete(NULL) is perfectly valid, so I guess free(NULL) should also be.
    • AnT stands with Russia
      AnT stands with Russia over 14 years
      @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.
    • Vijay
      Vijay over 14 years
      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?
    • GManNickG
      GManNickG over 14 years
      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.
    • AnT stands with Russia
      AnT stands with Russia over 14 years
      @benjamin: Huh? What made you to conclude that you can replace free(ptr) with ptr = NULL. No one said anything like that.
    • Heath Hunnicutt
      Heath Hunnicutt over 14 years
      @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.
    • dmckee --- ex-moderator kitten
      dmckee --- ex-moderator kitten over 14 years
  • Vijay
    Vijay over 14 years
    do u mean taht free will not perform anything?
  • AnT stands with Russia
    AnT stands with Russia over 14 years
    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).
  • Michael Krelin - hacker
    Michael Krelin - hacker over 14 years
    benjamin, that's exactly what it means. What would you expect it to perform if it's aware of nullness of the argument?
  • GManNickG
    GManNickG over 14 years
    You cannot delete void* either :P Which destructors(s) should it run?
  • AnT stands with Russia
    AnT stands with Russia over 14 years
    @GMan: You can delete void * as long as it is a null-pointer.
  • Vijay
    Vijay over 14 years
    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?
  • Prasoon Saurav
    Prasoon Saurav over 14 years
    No, ptr=NULL is no way a replacement for free(ptr), both are completely different
  • Gregory Pakosz
    Gregory Pakosz over 14 years
    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()
  • Prasoon Saurav
    Prasoon Saurav over 14 years
    ptr=NULL ensures that even if you accidently call free(ptr) your program won't segfault.
  • GManNickG
    GManNickG over 14 years
    You don't need to ask your question multiple times. Edit your question post and append the information you want.
  • GManNickG
    GManNickG over 14 years
    Ok, fair enough. I forgot we're only dealing specifically with null.
  • Tomas
    Tomas over 14 years
    -1 [citation needed]. Changing code-style because of some theory of an archaic hearsay implementation is a bad idea.
  • R Samuel Klatchko
    R Samuel Klatchko over 14 years
    @Tomas - I never recommended changing style, I simply explained why you may still see this recommendation in some styles.
  • Douglas Leeder
    Douglas Leeder about 14 years
    Interesting - that makes a second platform (after 3BSD) that crashes.
  • Douglas Leeder
    Douglas Leeder about 14 years
    @Tomas 3BSD (winehq.org/pipermail/wine-patches/2006-October/031544.html) and PalmOS for two (2nd hand for both).
  • Jonathan Leffler
    Jonathan Leffler about 14 years
    @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.
  • neuro
    neuro about 14 years
    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 :)
  • Derick
    Derick over 11 years
    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.
  • WereWolfBoy
    WereWolfBoy about 11 years
    @Derick avoid calling free? How do you free your memory then?
  • Gregory Pakosz
    Gregory Pakosz about 11 years
    @WereWolfBoy he means avoid free(NULL) by testing the pointer against NULL before calling free()
  • WereWolfBoy
    WereWolfBoy about 11 years
    @GregoryPakosz ah, that makes sense. Sorry :D
  • Calmarius
    Calmarius over 10 years
    Netware crashes on free-ing NULL too... (just debugged a crash on it...)
  • Steven Fisher
    Steven Fisher about 9 years
    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.
  • Franklin Yu
    Franklin Yu over 7 years
    @Calmarius That's why they are discontinued? LOL
  • jww
    jww over 6 years
    "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.
  • arthropod
    arthropod almost 6 years
    Interesting fact, caught me by surprise. Made me feel compelled to take a trip around NULL pointer questions/answers.
  • hanshenrik
    hanshenrik over 5 years
    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)
  • MadScientist
    MadScientist over 5 years
    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.
  • jamesdlin
    jamesdlin over 3 years
    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.
  • Polluks
    Polluks over 3 years
    However you will never free this port.
  • user16217248
    user16217248 over 2 years
    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
  • Lundin
    Lundin almost 2 years
    @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.