Does free(ptr) where ptr is NULL corrupt memory?
Asked Answered
S

11

153

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?

Subtle answered 21/12, 2009 at 7:43 Comment(8)
not sure about C free standard, but in C++ delete(NULL) is perfectly valid, so I guess free(NULL) should also be.Muzzleloader
@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.Township
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?Subtle
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.Myron
@benjamin: Huh? What made you to conclude that you can replace free(ptr) with ptr = NULL. No one said anything like that.Township
@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.Mountebank
Duplicate: #1880050Osteopathy
@Subtle free() deals with the right of a pointer variable to use memory (that variable's ownership of a block of memory), NOT what values are stored in/at that memory location. free( someIntPointer ) ===> tellOperatingSystemThat_someIntPointer_noLongerHasRightsToReadNorWrite_sizeOfInteger_AmountOfMemory. ptr = NULL; means that the pointer is pointing to memory address 0x00000000 (there may be more hex 0s added to the end of that number, but it still has memory address 0). This statement is NOT saying what data lies at that address, nor how many bytes will be stored there (since no type)Haynor
C
267

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.

Carmelitacarmelite answered 21/12, 2009 at 7:50 Comment(9)
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?Subtle
No, ptr=NULL is no way a replacement for free(ptr), both are completely differentLunitidal
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()Carmelitacarmelite
ptr=NULL ensures that even if you accidently call free(ptr) your program won't segfault.Lunitidal
You don't need to ask your question multiple times. Edit your question post and append the information you want.Myron
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.Maestricht
@Maestricht avoid calling free? How do you free your memory then?Stop
@Stop he means avoid free(NULL) by testing the pointer against NULL before calling free()Carmelitacarmelite
@GregoryPakosz ah, that makes sense. Sorry :DStop
N
34

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);
Nescience answered 21/12, 2009 at 8:2 Comment(9)
-1 [citation needed]. Changing code-style because of some theory of an archaic hearsay implementation is a bad idea.Shanaeshanahan
@Shanaeshanahan - I never recommended changing style, I simply explained why you may still see this recommendation in some styles.Nescience
@Shanaeshanahan 3BSD (winehq.org/pipermail/wine-patches/2006-October/031544.html) and PalmOS for two (2nd hand for both).Adeleadelheid
@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.Ammeter
Netware crashes on free-ing NULL too... (just debugged a crash on it...)Lindquist
@Lindquist That's why they are discontinued? LOLRivy
"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.Jalbert
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.Imprest
@Jalbert 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.Lofty
R
15

If ptr is NULL, no operation is performed.

says the documentation.

Robeson answered 21/12, 2009 at 7:46 Comment(2)
do u mean taht free will not perform anything?Subtle
benjamin, that's exactly what it means. What would you expect it to perform if it's aware of nullness of the argument?Robeson
M
13

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

Mottled answered 27/12, 2009 at 12:43 Comment(3)
Interesting - that makes a second platform (after 3BSD) that crashes.Adeleadelheid
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.Drawing
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.Karyotin
L
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.

Lunitidal answered 21/12, 2009 at 7:47 Comment(0)
I
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.

Inflation answered 21/12, 2009 at 8:38 Comment(1)
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 :)Schliemann
P
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.

Policlinic answered 21/12, 2009 at 7:47 Comment(5)
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).Township
You cannot delete void* either :P Which destructors(s) should it run?Myron
@GMan: You can delete void * as long as it is a null-pointer.Township
Ok, fair enough. I forgot we're only dealing specifically with null.Myron
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)Watchful
J
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.

Janik answered 19/10, 2017 at 8:39 Comment(2)
Interesting fact, caught me by surprise. Made me feel compelled to take a trip around NULL pointer questions/answers.Evergreen
However you will never free this port.Menon
S
1

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

Sophisticate answered 21/12, 2009 at 7:45 Comment(0)
T
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;  \
    }                  \
}
Tangram answered 14/5, 2023 at 6:56 Comment(0)
M
-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.

Masha answered 10/9, 2015 at 14:15 Comment(2)
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 errorArteriole
Order matters. free(ptr); ptr=NULL; is extremely different from ptr=NULL; free(ptr); The first deallocates the memory (variable gets its read/write rights to that chunk of memory revoked) and then removes any way of accessing that memory, which is completely safe and fine (as long as you never assign anything to ptr without also allocating new memory to ptr in the future). The second removes any way of accessing that memory (ptr=NULL;), then tries to access it in order to revoke its rights (via free(ptr))!Haynor

© 2022 - 2024 — McMap. All rights reserved.