In my code almost every function has one or more malloc calls, and each time I have to do something like:
char *ptr = (char *)malloc(sizeof(char) * some_int);
if (ptr == NULL) {
fprintf(stderr, "failed to allocate memory.\n");
return -1;
}
that's four extra lines of code and if I add them everytime after I use a malloc, the length of my code will increase a lot.. so is there an elegant way to deal with this?
Thank you so much!!
Sorry, but there's nothing you can do about that in C. Except... gasp... wrap it all in a macro which will automate the
if
check and allow you to write custom error-handling code each time. There, I said it.Seriously, C isn't meant to provide conveniences like this. If you don't mind exiting the program on the spot, you can wrap it in a function of course that does
exit
when the allocation fails -- but that's no general solution.When you have no real error handling (except printing something and exiting), the simple and established solution is to define a function safe_malloc which incorporates the check. (Edit: Or, of course, a macro. Whatever rocks your boat.)
There isn't usually much point in trying to stumble on when all memory is consumed. Might as well call it quits:
You could use macros. This is cheaper than grouping this code into a function because Macros don't have the overhead a function call incurs. Macros are expanded by the preprocessor stage of compilation and can be verified by the '-E' option in gcc. Now say we have func1(), func2(), func3()
Or you could use an extern.
Define a function in main.c:
Any file that mallocs memory add as you would a forward declaration:
Now write malloc as:
The linkage between the place in your code where you malloc'd memory and main.c that handles the exception is generated behind the scenes by the linker; it maps calls to the function with the function even though the two exist in different source files.
C runtime should clean up any resources, including open files, buffers, and allocated data. Even so, I like to use
int atexit( void(*)(void))
which will call registered functions upon a normal exit. Also exit immediately ifatexit
returns a non-zero value, meaning your function was not registered.Then exit on malloc failure.