You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 2 Next »

Many functions require the allocation of multiple objects. Failing and returning somewhere in the middle of this function without freeing all of the allocated memory could produce a memory leak. It is a common error to forget to free one (or all) of the objects in this manner, so a goto-chain is the simplest and cleanest way to organize exits when order is preserved.

Noncompliant Code Example

int do_something(void){
  // ... definitions ...

  obj1 = malloc(...);
  if (!obj1){
    return -1;
  }

  obj2 = malloc(...);
  if (!obj2){
    free(obj1);
    return -1;
  }

  obj3 = malloc(...);
  if (!obj3){
    free(obj2);
    return -1; // Forgot to free obj1 -- Memory leak
  }

  // ... more code ...
}

Notice how there is a memory leak if obj3 cannot be allocated. This is also just a small example; in much larger examples, errors like this would be even harder to detect. Hence, the goto-chain...

Compliant Solution

int do_something(void){
  // ... definitions ,,,

  obj1 = malloc(...);
  if (!obj1){
    goto FAIL_OBJ1;
  }

  obj2 = malloc(...);
  if (!obj2){
    goto FAIL_OBJ2;
  }

  obj3 = malloc(...);
  if (!obj3){
    goto FAIL_OBJ3;
  }

?
  // ... more code ...


FAIL_OBJ3:
  free(obj2);

FAIL_OBJ2:
  free(obj1);

FAIL_OBJ1:
  return -1;
}

This code is guaranteed to clean up properly whenever an allocation fails.  It is cleaner and prevents rewriting of similar code upon every function error.

  • No labels