0

I have a preprocessor define:

#include "stdio.h"
#define FREE(ptr) free(ptr)

And I want to know if it is safe to change it to:

#include "stdio.h"
#define FREE(ptr) free(ptr); \
        (ptr) = null;

for code safe.

I think that because free is returning void so it can't be chained as shown at that question so it will be safe, but I'm not sure.

arye
  • 458
  • 3
  • 15

3 Answers3

2

Your original is missing a semicolon, and this usage would not work after a control statement (if, else, while, for...) if not inside a block statement { ... }.

Since free does not return a value, for maximal compatibility (excepting the function pointer use, or use within comma operator. freeing the return value of a function, incrementing in call to free and other dubious tricks...) you could use the very common trick of wrapping into do { } while (0). The do { } while (0) will eat the following semicolon, and work alike even in nested if...else.

Therefore:

#define FREE(ptr) do { free(ptr); ptr = 0; } while (0)
  • good answer, but still I will have the double evaluation problem that @chux - Reinstate Monica mentioned. – arye Sep 24 '20 at 10:57
1

Fails in at least 3 ways:

#define FREE(ptr) free(ptr) \
    (ptr) = null;

null not define.

Not tied together. Consider

if (test) FREE(ptr);

is like

if (test) free(ptr);
ptr = null;

Double evaluation

FREE(foo());

is like

free(foo());
foo() = null;
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
0

You probably want this:

#define FREE(ptr) do {free(ptr); \
        (ptr) = NULL;} while (0)

instead of this:

#define FREE(ptr) free(ptr) \
        (ptr) = null;

...
int* a = malloc(10);
printf(" a = %p\n", (void*)a);
FREE(a);
printf(" a = %p\n", (void*)a);
...

This code snippet should print something similar to this:

a = 01bb95d9
a = 00000000

Read this for more information about the do... while(0) stuff.

A cleaner solution would be to put this into a function like this:

void FREE(void **ptr)
{
  free(*ptr);
  *ptr = NULL;
}

and call it like this:

int *a = malloc(10);
FREE(&a);
// a is NULL here
Jabberwocky
  • 48,281
  • 17
  • 65
  • 115