I would like to wrap my calls to malloc/realloc into a macro that would stop the program if the method returns NULL
can I safely use the following macro?
#define SAFEMALLOC(SIZEOF) (malloc(SIZEOF) || (void*)(fprintf(stderr,"[%s:%d]Out of memory(%d bytes)\n",__FILE__,__LINE__,SIZEOF),exit(EXIT_FAILURE),0))
char* p=(char*)SAFEMALLOC(10);
it compiles, it works here with SAFEMALLOC(1UL)
and SAFEMALLOC(-1UL)
but is it a safe way to do this?
static void* safe_malloc(size_t n, unsigned long line)
{
void* p = malloc(n);
if (!p)
{
fprintf(stderr, "[%s:%ul]Out of memory(%ul bytes)\n",
__FILE__, line, (unsigned long)n);
exit(EXIT_FAILURE);
}
return p;
}
#define SAFEMALLOC(n) safe_malloc(n, __LINE__)
No, it's broken.
It seems to assume that the boolean or operator ||
returns its argument if it's deemed true, that's not how it works.
C's boolean operators always generate 1
or 0
as integers, they do not generate any of the input values.
Using your macro:
#define SAFEMALLOC(SIZEOF) (malloc(SIZEOF) || (void*)(fprintf(stderr,"[%s:%d]Out of memory(%d bytes)\n",__FILE__,__LINE__,SIZEOF),exit(EXIT_FAILURE),0))
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char *p = SAFEMALLOC(10);
char *q = SAFEMALLOC(2000);
printf("p = %p, q = %p\n", p, q);
// Leak!
return 0;
}
Warnings (should be a clue):
weird.c:8: warning: cast to pointer from integer of different size
weird.c:8: warning: initialization makes pointer from integer without a cast
weird.c:9: warning: cast to pointer from integer of different size
weird.c:9: warning: initialization makes pointer from integer without a cast
Output:
p = 0x1, q = 0x1
In summary, no, it's not very safe! Writing a function would probably be less error prone.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.