Alex Rivera | Logout

Why doesn't free(p) set p to NULL?

Asked 2010-04-16T09:33:50.067
17

Any reasons why this can not be standard behavior of free()?

multiple pointers pointing to the same object:

#include <stdlib.h>
#include <stdio.h>

void safefree(void*& p)
{
    free(p); p = NULL;
}

int main()
{
    int *p = (int *)malloc(sizeof(int));
    *p = 1234;
    int*& p2 = p;
    printf("p=%p p2=%p\n", p, p2);
    safefree((void*&)p2);
    printf("p=%p p2=%p\n", p, p2);
    safefree((void*&)p); // safe

    return 0;
}

assignment from malloc demands cast from void*

vice versa:

safefree() demands cast to void*& (reference)

Edit
Report

2 Answers

2

With reference to the quote from Stroustrup about delete, Peter Norvig also makes a similar remark. He writes (not about C++!):

"Nothing is destroyed until it is replaced"
 - Auguste Comte (1798-1857) (on the need for revolutionary new
   theories (or on the need to do x.f = null in garbage-collected
   languages with destructors))

In my C code, I find the following macro very useful:

#define free(p) free((void *)(p)),(p)=NULL /* zero p */

This, as written, uses its argument twice. But this isn't a problem, as any usage such as free(p++) or free(find_named_object("foo")) will give a compile-time error (lvalue required). And you can hide the macro by using (free)(p++), or by calling it something else e.g. FREE.

answered 2010-04-16T17:21:24.037
0

Casting the reference from int *& to void *& is not guaranteed to work. int * simply does not have to have the same size, representation nor alignment requirements as void *.

The proper C++ solution would be to use templates, as Neil Butterworth suggests in a comment. And neither of these ways work in C, obviously - which is where free() comes from.

answered 2010-04-16T23:37:27.810

Your Answer