473,396 Members | 1,995 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

free() question

I apologize if this is a stupid question. I was just curious... is
there any reason why free() doesn't set the pointer (that was passed to
it) to NULL after giving the memory back to the heap? I decided to
write a wrapper for free() to do just that, and I wondered why free()
itself didn't do it.

Aaron
--
/usr/bin/fortune says:
How can you work when the system's so crowded?

Nov 14 '05 #1
12 1595
Aaron Walker wrote:

I apologize if this is a stupid question. I was just curious... is
there any reason why free() doesn't set the pointer (that was passed to
it) to NULL after giving the memory back to the heap? I decided to
write a wrapper for free() to do just that, and I wondered why free()
itself didn't do it.

There are no stupid questions. As designed, free() receives a value, the
address of the allocation to be freed. It doesn't know where the value
came from. Consider..

int *arr, *tmp;
arr = malloc(N * sizeof *arr);
tmp = arr;

...Both arr and tmp hold the address of memory returned by malloc(). It
doesn't make any difference now whether I call..

free(arr);
or
free(tmp);

...because the free() function receives the address of the allocation and
no information about arr or tmp at all. It is not possible for free() to
set them to NULL.
--
Joe Wright http://www.jw-wright.com
"Everything should be made as simple as possible, but not simpler."
--- Albert Einstein ---
Nov 14 '05 #2
Aaron Walker <ka*****@REMOVETHIScfl.rr.com> wrote in message news:<3P*********************@twister.tampabay.rr. com>...
I apologize if this is a stupid question. I was just curious... is
there any reason why free() doesn't set the pointer (that was passed to
it) to NULL after giving the memory back to the heap?


It's not a stupid question, but it *is* a FAQ (7.21)

If free() modified its argument like this it wouldn't be implementable
as a C function.

-thomas
Nov 14 '05 #3
Aaron Walker wrote:
I apologize if this is a stupid question. I was just curious... is
there any reason why free() doesn't set the pointer (that was passed to
it) to NULL after giving the memory back to the heap? I decided to
write a wrapper for free() to do just that, and I wondered why free()
itself didn't do it.

Aaron


Some of use don't believe this would be a particularly useful feature.
If the goal is to be able to test a pointer in order to determine
whether it still points to valid accessible memory, a test against NULL
is not sufficient. Consider:

int *p1 = malloc(5 * sizeof *p1);
int *p2 = p1;
magic_free_and_NULL(p1);

if (p1 != NULL) /* OK */
{
p1[0] = 1234;
}

if (p2 != NULL) /* BAM! Undefined. */
{
p2[1] = 4321; /* BAM! Undefined. */
}

In this example, it's not even safe to test p2, let alone dereference
it. (The value of a pointer to memory that has been freed is indeterminate.)

Also, consider this:

free(p - 1);

What should be set to NULL here?

Setting freed pointers to NULL is handy in some cases, but is not good
as a general technique for determining when memory has been freed.

-Kevin
--
My email address is valid, but changes periodically.
To contact me please use the address from a recent posting.
Nov 14 '05 #4
On Fri, 26 Dec 2003 14:44:15 GMT, Aaron Walker
<ka*****@REMOVETHIScfl.rr.com> wrote:
I apologize if this is a stupid question. I was just curious... is
there any reason why free() doesn't set the pointer (that was passed to
it) to NULL after giving the memory back to the heap? I decided to
write a wrapper for free() to do just that, and I wondered why free()
itself didn't do it.

free() does not receive the pointer. C passes arguments by value.
That means that free() receives a copy of the pointer (just its
value). How would you suggest that free() trace this value back to
the variable that contains it?

This question is asked here in various guises quite frequently and is
covered in the faq. The basic answer is that a function cannot affect
the variables that contain the calling arguments.
<<Remove the del for email>>
Nov 14 '05 #5
On Fri, 26 Dec 2003 16:48:38 +0000, Joe Wright wrote:
Aaron Walker wrote:

I apologize if this is a stupid question. I was just curious... is
there any reason why free() doesn't set the pointer (that was passed to
it) to NULL after giving the memory back to the heap? I decided to
write a wrapper for free() to do just that, and I wondered why free()
itself didn't do it.

There are no stupid questions. As designed, free() receives a value, the
address of the allocation to be freed. It doesn't know where the value
came from. Consider..

int *arr, *tmp;
arr = malloc(N * sizeof *arr);
tmp = arr;

..Both arr and tmp hold the address of memory returned by malloc(). It
doesn't make any difference now whether I call..

free(arr);
or
free(tmp);

..because the free() function receives the address of the allocation and
no information about arr or tmp at all. It is not possible for free() to
set them to NULL.


Exactly. And nothing more is necessary within the standard C library.
It would be trivial to implement one's own function which takes a handle
and sets the pointer to null, thus solving the problem without adding more
unnecessary cruft to the C library, as it appears the parent poster has
already done.

void nullfree ( void **blk )
{
free (*blk);
*blk = NULL;
}
Nov 14 '05 #6
in comp.lang.c i read:
nothing more is necessary within the standard C library.
necessary -- or unnecessary?
It would be trivial to implement one's own function which takes a handle
and sets the pointer to null, thus solving the problem without adding more
unnecessary cruft to the C library, as it appears the parent poster has
already done.

void nullfree ( void **blk )
{
free (*blk);
*blk = NULL;
}


that could only assign a null pointer to the variable whose address was
passed; what of any aliases? code sloppy enough to use a pointer after it
has been free'd probably has many aliases too, yet those are not handled,
so remain armed bombs. sometimes just clearing the one pointer is enough,
and so plenty of people do have a FREE(p) macro that expands to `do {
free(p); p=0; } while (0)'. but it takes some care to keep from falling
into the trap of complacency -- which a platform that makes it clear when a
null pointer is used, e.g., by stopping the program in a very visible way
-- can help reinforce, and if it becomes ingrained any aliases are nearly
certain to bite, though perhaps not right away.

--
a signature
Nov 14 '05 #7
Michael Baehr wrote:
It would be trivial to implement one's own function which takes a handle
and sets the pointer to null, thus solving the problem without adding more
unnecessary cruft to the C library, as it appears the parent poster has
already done.

void nullfree ( void **blk )
{
free (*blk);
*blk = NULL;
}


This is great if you happen to use void * a lot, but it is not guaranteed to
work for other kinds of pointer. For example:

int *p = malloc(n * sizeof *p);
if(p != NULL)
{
use(p, n);
nullfree(&p); /* undefined behaviour */
}

void * is a generic pointer type, but void ** is not.

You could do this:

int *p = malloc(n * sizeof *p);
if(p != NULL)
{
void *q = p;
use(p, n);
nullfree(&q);
}

but what's the point?

--
Richard Heathfield : bi****@eton.powernet.co.uk
"Usenet is a strange place." - Dennis M Ritchie, 29 July 1999.
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
K&R answers, C books, etc: http://users.powernet.co.uk/eton
Nov 14 '05 #8
"Richard Heathfield" <do******@address.co.uk.invalid> wrote:
Michael Baehr wrote:
void nullfree ( void **blk )
{
free (*blk);
*blk = NULL;
}
This is great if you happen to use void * a lot, but it is not
guaranteed to work for other kinds of pointer. For example:

int *p = malloc(n * sizeof *p);
if(p != NULL)
{
use(p, n);
nullfree(&p); /* undefined behaviour */


Constraint violation, in fact. However even with the cast
nullfree((void **)&p) is still undefined behaviour.
}

void * is a generic pointer type, but void ** is not.


And the reason I know that is by reading C Unleashed and the
woes over the interface for a wrapper for realloc. :-)

--
Simon.
Nov 14 '05 #9
Simon Biber wrote:
"Richard Heathfield" <do******@address.co.uk.invalid> wrote:
Michael Baehr wrote:
> void nullfree ( void **blk )
> {
> free (*blk);
> *blk = NULL;
> }
This is great if you happen to use void * a lot, but it is not
guaranteed to work for other kinds of pointer. For example:

int *p = malloc(n * sizeof *p);
if(p != NULL)
{
use(p, n);
nullfree(&p); /* undefined behaviour */


Constraint violation, in fact.


Good Lord, so it is. Thanks.
However even with the cast
nullfree((void **)&p) is still undefined behaviour.
}

void * is a generic pointer type, but void ** is not.


And the reason I know that is by reading C Unleashed and the
woes over the interface for a wrapper for realloc. :-)


What goes around, comes around.

(Incidentally, even in the little monologue you describe, I managed to
introduce a common error - taking the address of an rvalue!)

--
Richard Heathfield : bi****@eton.powernet.co.uk
"Usenet is a strange place." - Dennis M Ritchie, 29 July 1999.
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
K&R answers, C books, etc: http://users.powernet.co.uk/eton
Nov 14 '05 #10
"Simon Biber" <ne**@ralminNOSPAM.cc> wrote in message
news:3f***********************@news.syd.swiftdsl.c om.au...
"Richard Heathfield" <do******@address.co.uk.invalid> wrote:
Michael Baehr wrote:
void nullfree ( void **blk )
{
free (*blk);
*blk = NULL;
}
This is great if you happen to use void * a lot, but it is not
guaranteed to work for other kinds of pointer. For example:

int *p = malloc(n * sizeof *p);
if(p != NULL)
{
use(p, n);
nullfree(&p); /* undefined behaviour */


Constraint violation, in fact.


Yes, but curiously (it would seem) by 6.5.16.1p1 (assignment operators), not
by 6.5.2.2p1 (function calls).
However even with the cast
nullfree((void **)&p) is still undefined behaviour.


True, because the cast itself (or more precisely the conversion of &p, be it
explicit or implicit) potentially invokes undefined behaviour if the
resultant void** pointer is not properly aligned (6.3.2.3p5).

If the conversion _is_ aligned then the function call itself does not invoke
UB (by virtue of 6.3.2.3p5 and 6.5.16.1p2), although UB will occur at
evaluation of *blk in nullfree.
}


--
Peter
Nov 14 '05 #11
"Kevin Goodsell" <us*********************@neverbox.com> wrote in message
news:cV0Hb.20432
int *p1 = malloc(5 * sizeof *p1);
int *p2 = p1;
magic_free_and_NULL(p1);

if (p1 != NULL) /* OK */
{
p1[0] = 1234;
}

if (p2 != NULL) /* BAM! Undefined. */


I have a vague recollection about this being undefined, but I can't imagine
a case where it would fail.
Care to explain?
Nov 14 '05 #12
Servé Lau wrote:
"Kevin Goodsell" <us*********************@neverbox.com> wrote in message
news:cV0Hb.20432
int *p1 = malloc(5 * sizeof *p1);
int *p2 = p1;
magic_free_and_NULL(p1);

if (p1 != NULL) /* OK */
{
p1[0] = 1234;
}

if (p2 != NULL) /* BAM! Undefined. */

I have a vague recollection about this being undefined, but I can't imagine
a case where it would fail.
Care to explain?


It will probably behave as expected on almost all implementations. But
imagine a hypothetical system with special-purpose address registers and
protected memory. Loading an address into these registers causes the
validity of the address to be checked, and some kind of exception occurs
for an invalid address. Once the memory at some address has been freed,
that address is marked invalid, so loading that address into one of the
address registers would cause an exception.

-Kevin
--
My email address is valid, but changes periodically.
To contact me please use the address from a recent posting.
Nov 14 '05 #13

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

9
by: zerro | last post by:
Hello, I try to understand heap overflows (under Linux), but can not understand one thing with freeing memory allocated with malloc(). Here it comes: I have a program called 1.c: main() {...
36
by: Martin Andert | last post by:
Hello, I have a question regarding malloc and free. Here my code sample: int main() { /* allocating dynamic memory for array */ int* array = (int*) malloc(5 * sizeof(int)); /* ... program...
17
by: kj | last post by:
How can one test if a pointer has been "freed" (i.e. with free())? My naive assumption was that such a pointer would equal NULL, but not so. Thanks, kj -- NOTE: In my address everything...
86
by: Walter Roberson | last post by:
If realloc() finds it necessary to move the memory block, then does it free() the previously allocated block? The C89 standard has some reference to undefined behaviour if one realloc()'s memory...
19
by: lawtrevor | last post by:
I have a question regarding the use of free() based on some code I need to decipher: { struct A {<A fields>}; struct B {<A fields+ <Bfields>}; typedef struct A Aobj; typedef struct B Bobj;
76
by: dbansal | last post by:
Hi group, I have a question to ask you all. I have allocated some chunk of memory using ptr=(int*)malloc(). now I am trying to free that memory using free((void*)ptr). My question is does free()...
13
by: Berk Birand | last post by:
Hi, I am working on a school project where we use lex/yacc to write a compiler for a fictional (Java-like) language. I have handled all the details about the yacc and lex files, but I still have...
13
by: Chad | last post by:
Excercise 6-5 Write a functon undef that will remove a name and defintion from the table maintained by lookup and install. Code: unsigned hash(char *s); void undef(char *s)
2
by: Workarounder | last post by:
Hi! I have a program and in this program I have to do a lot of close´s and free´s. The program is something like this: static int finalize(FILE* f1, FILE* f2, char* c) { if (f1 != NULL) { ...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.