Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

To write robust C program, how do you avoid too many different free () combinations?

For example, I need to malloc two pieces of memory, so:

void *a = malloc (1);

if (!a)
  return -1;

void *b = malloc (1);

if (!b)
{
  free (a);
  return -1;
}

Notice if the second malloc fails, I have to free "a" first. The problem is, this can be very messy if there are many such malloc's and error checking's, unless I use the notorious "goto" clause and carefully arrange the order of free's along with the labels:

void *a = malloc (1);

if (!a)
  goto X;

void *b = malloc (1);

if (!b)
  goto Y;

return 0; //normal exit

Y:
  free (a);
X:
  return -1;

Do you have any better solution to this situation? Thanks in advance.

like image 593
Kun Wu Avatar asked Mar 28 '12 06:03

Kun Wu


3 Answers

We do like this:

void *a = NULL;
void *b = NULL;
void *c = NULL;
a = malloc(1);
if (!a) goto errorExit;
b = malloc(1);
if (!b) goto errorExit;
c = malloc(1);
if (!b) goto errorExit;

return 0;
errorExit:
//free a null pointer is safe.
free(a);
free(b);
free(c);
return -1;
like image 117
RolandXu Avatar answered Nov 23 '22 08:11

RolandXu


Using goto is not a bad thing, in my opinion. Using it for resource cleanup is just right for it.

Source code as famous as the Linux kernel uses the technique.

Just don't use goto to go backwards. That leads to disaster and confusion. Only jump forward is my recommendation.

like image 40
Zan Lynx Avatar answered Nov 23 '22 06:11

Zan Lynx


As previously mentioned by Zan Lynx use goto statement.

You can also alloc larger chunk of memory for further use.

Or you can invest your time to develop something like memory pool.

like image 37
jacekmigacz Avatar answered Nov 23 '22 06:11

jacekmigacz