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

Compare with Current View Page History

« Previous Version 3 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.

Recommendation

Severity

Likelihood

Remediation Cost

Priority

Level

MEM86-C

low

probable

medium

P3

L3

  • No labels