Your code is fine, but for lots of variables, I’d prefer:
int
foo()
{
char *p = NULL;
char *q = NULL;
int ret = 0;
if (NULL == (p = malloc(BUFSIZ)))
{
ret = ERROR_CODE;
goto error;
}
// possibly do something here
if (NULL == (q = malloc(BUFSIZ)))
{
ret = ERROR_CODE;
goto error;
}
// insert similar repetitions
// hopefully do something here
error:
free (p);
free (q);
return ret;
}
Note that freeing NULL
is defined as a no-op.
This avoids n
levels of indent for n
variables. You can clean up filehandles etc. similarly (though you’ll have to put a condition around the close()
).
Now, if you know you can allocate them all at once, then dasblinkenlight has a good answer, but here’s another way:
int
foo()
{
int ret = 0;
char *p = malloc(BUFSIZ);
char *q = malloc(BUFSIZ);
char *r = malloc(BUFSIZ);
if (!p || !q || !r)
{
ret = ERROR_CODE;
goto exit;
}
// do something
exit:
free(p);
free(q);
free(r);
return ret;
}
Final possibility: if you actually want to exit the program on malloc
fail, consider using mallopt
‘s M_CHECK_ACTION
option. This makes malloc()
faults get checked, and calls abort()
, possibly printing a helpful message.
From the man page:
NAME
mallopt
– set memory allocation parametersSYNOPSIS
#include <malloc.h> int mallopt(int param, int value);
DESCRIPTION
The
mallopt()
function adjusts parameters that control the behavior of the memory-allocation functions (seemalloc(3)
). Theparam
argument specifies the parameter to be modified, andvalue
specifies the new value for that parameter.The following values can be specified for
param
:
M_CHECK_ACTION
Setting this parameter controls how glibc responds when various kinds of programming errors are detected (e.g., freeing the same pointer twice). The 3 least significant bits (2, 1, and 0) of the value assigned to this parameter determine the glibc behavior, as follows:
Bit 0: If this bit is set, then print a one-line message on
stderr
that provides details about the error. The message starts with the string"*** glibc detected ***"
, followed by the program name, the name of the memory-allocation function in which the error was detected, a brief description of the error, and the memory address where the error was detected.Bit 1: If this bit is set, then, after printing any error message specified by bit 0, the program is terminated by calling
abort(3)
. In glibc versions since 2.4, if bit 0 is also set, then, between printing the error message and aborting, the program also prints a stack trace in the manner ofbacktrace(3)
, and prints the process’s memory mapping in the style of/proc/[pid]/maps
(seeproc(5)
).Bit 2: (since glibc 2.4) This bit has an effect only if bit 0 is also set. If this bit is set, then the one-line message describing the error is simplified to contain just the name of the function where the error was detected and the brief description of the error.