Reputation: 147
I have seen a few different ways of doing malloc error checking. Is one way better than the other? Are some exit codes better than others? Is using fprintf with stderr better than using a printf statement? Is using a return instead of an exit better?
ptr=(int*)malloc(n*sizeof(int)); //memory allocated using malloc
if(ptr==NULL)
{
printf("Error! memory not allocated.");
exit(0);
}
ptr=(int*)malloc(n*sizeof(int)); //memory allocated using malloc
if(ptr==NULL)
{
printf("Error! memory not allocated.");
exit(1);
}
res = malloc(strlen(str1) + strlen(str2) + 1);
if (!res) {
fprintf(stderr, "malloc() failed: insufficient memory!\n");
return EXIT_FAILURE;
}
ptr=(int*)malloc(n*sizeof(int)); //memory allocated using malloc
if(ptr==NULL)
{
printf("Error! memory not allocated.");
exit(-1);
}
ptr=(int*)malloc(n*sizeof(int)); //memory allocated using malloc
if(ptr==NULL)
{
printf("Error! memory not allocated.");
exit(EXIT_FAILURE);
}
char *ptr = (char *)malloc(sizeof(char) * some_int);
if (ptr == NULL) {
fprintf(stderr, "failed to allocate memory.\n");
return -1;
}
char* allocCharBuffer(size_t numberOfChars)
{
char *ptr = (char *)malloc(sizeof(char) * numberOfChars);
if (ptr == NULL) {
fprintf(stderr, "failed to allocate memory.\n");
exit(-1);
}
return ptr;
}
Upvotes: 11
Views: 39316
Reputation: 5339
When you detect an error with malloc()
, calloc()
and realloc()
(i.e they return a NULL pointer), the POSIX98 standard dictates that errno
must be set (see man malloc
). You can then use the standard function perror()
to print the error without the need to do your own formatting. Note that it will automatically print to stderr
, no need to bother with that.
Furthermore, If your application considers the error as fatal, then the process must be ended. If your code is located in the main()
function, then using return EXIT_FAILURE;
is fine, and use exit(EXIT_FAILURE);
if not. It is not recommended to exit with your own return code in that case.
If the error is not considered as fatal, then it's up to you how to handle it.
Please also note that, when realloc()
fails and returns NULL
, the old pointer is still valid and must therefore be free
d before leaving.
Upvotes: 13
Reputation: 137398
How about this wrapper:
void *safe_malloc(size_t n)
{
void *p = malloc(n);
if (p == NULL) {
fprintf(stderr, "Fatal: failed to allocate %zu bytes.\n", n);
abort();
}
return p;
}
Then just use safe_malloc
everywhere, and don't worry about the error checking.
Many programs are not written to gracefully handle memory allocation failures, and this solution is just fine for those applications. If your application is able to continue after memory allocation failures, then you probably wouldn't be asking this question.
Upvotes: 15
Reputation: 47952
Rule #1. Always check malloc
's return value (and realloc
's) for errors.
Rule #2. Unless you can recover gracefully, always print an error message to stderr
, giving relevant information.
Rule #3. Always exit with a nonzero status of there is an error. (The exact nonzero value doesn't matter so much.)
A "wrapper" function is an excellent way of addressing all three rules at the same time, if your program can tolerate exiting precipitously (that is, without saving any in-memory data which might be vital).
There are some exceptions to Rule #2, but they still involve reporting the error somehow (just not necessarily with an immediate fprintf
to stderr
), so the basic rule stands.
Upvotes: 1
Reputation: 60068
perror("more details");
will (attempt to) print the error (as per the errno) to stderr
.
You can use that.
static void die(const char* msg){ perror(msg); exit(1); }
You could also save the errno and translate it to a BSD style sysexits.h code or just somehow linearly serialize it to the parent process (by exit
ing with the errno or a linear translation thereof).
Upvotes: 0
Reputation: 4849
It is not about how you check the error, It is what you do with the error. In all the cases you can see that the common piece of code used is
if (ptr == NULL) {....}
When you encounter the return value is NULL
, what you do after that is your personal choice. Some devs even like to assert()
the program.
in the meantime gcc sets the errno for you. So you can use that to get more details and use it as well.
In summary you can do whatever suits you most for your program.
Upvotes: 2