4 ms·
Here's the actual macro I (sometimes) use: #define FREE(ptrptr) do { \ __typeof__(ptrptr) const __x = (ptrptr); \ free(*__x); *__x = NULL;
by btrask 6y ago
Here's the actual macro I (sometimes) use:
#define FREE(ptrptr) do { \
__typeof__(ptrptr) const __x = (ptrptr); \
free(*__x); *__x = NULL; \
} while(0)
There might be a better way of doing it though. Also, __typeof__() obviously isn't standard C.
Edit to add: I've honestly been moving away from using a macro and just putting both statements on one line like in the OP. For something so simple, using a macro seems like overkill.
- Thorrez 6y agoWhat's the benefit of that over nn3's version?
- dromtrund 6y agoIt'll only evaluate the pointer once. It's possible to make this a function though, that might be preferable
- btrask 6y agoI tried making it a plain function at one point but ran into some weirdness around using void * * with certain arguments (const buffers?). You don't want to accept plain void * because it's too easy to pass a pointer instead of a pointer to a pointer. Using a macro is (ironically) more type safe. Maybe someone else could figure out how to do it properly, since I'd definitely prefer a function.
- Thorrez 6y agoGood point. But it seems like it would require usage like this: int* p = malloc(sizeof(int)); FREE(&p); What if we instead define the macro like this: #define FREE(ptr) do { \ __typeof__(ptr)* const __x = &(ptr); \ free(*__x); *__x = NULL; \ } while(0) Then make usage slightly shorter, as well as more similar to free(): int* p = malloc(sizeof(int)); FREE(p);
- btrask 6y agoTaking a pointer-to-pointer is intentional to make it clear that the pointer will be modified. That's actually the most important difference from nn3's version IMHO.