Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

In this noncompliant code example, the memory referred to by x may be freed twice: once if error_condition is true and again at the end of the code.

Code Block
bgColor#FFCCCC
langc
int f(size_t n) {
  int error_condition = 0;

  int *x = (int*)malloc(n * sizeof(int));
  if (x == NULL)
    return -1;

  /* Use x and set error_condition on error. */

  if (error_condition == 1) {
    /* Handle error condition*/
    free(x);
  }

  /* ... */
  free(x);
  return error_condition;
}

...

In this compliant solution, the free a referenced by x is only freed once. This is accomplished by eliminating the call to free() when error_condition is set.

Code Block
bgColor#ccccff
langc
int f(size_t n) {
  int error_condition = 0;

  if (n > SIZE_MAX / sizeof(int)) {
    errno = EOVERFLOW;
    return -1;
  }

  int *x = (int*)malloc(n * sizeof(int));
  if (x == NULL) {
    /* Report allocation failure to caller. */
    return -1;
  }

  /* Use x and set error_condition on error. */

  if (error_condition != 0) {
    /* Handle error condition and proceed. */
  }

  free(x);

  return error_condition;
}

...

The memory referenced by p may be freed twice in this noncompliant code example.

Code Block
bgColor#FFCCCC
langc
/* p is a pointer to dynamically allocated memory */
p2 = realloc(p, size);
if (p2 == NULL) {
  free(p); /* p may be indeterminate when (size == 0) */
  return;
}

...

In this compliant solution, allocations of zero-bytes are prevented, ensuring that p is freed exactly once.

Code Block
bgColor#ccccff
langc
/* p is a pointer to dynamically allocated memory */
if (size) {
  p2 = realloc(p, size);
  if (p2 == NULL) {
    free(p);
    return;
  }
}
else {
  free(p);
  return;
}

...