Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Minor edits; reviewed

...

In this compliant solution, the free a memory 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
#include <stdlib.h>
 
int f(size_t n) {
  int error_condition = 0;

  if (n > SIZE_MAX / sizeof(int)) {
    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);

  x = 0;
  return error_condition;
}

Note that this solution checks for numeric overflow. (See INT32-C. Ensure that operations on signed integers do not result in overflow.)  It also complies with MEM01-C. Store a new value in pointers immediately after free()

Noncompliant Code Example (realloc())

...

Code Block
bgColor#FFCCCC
langc
#include <stdlib.h>
 
/* p is a pointer to dynamically allocated memory. */
void func(void *p, size_t size) {

  p2 = realloc(p, size);
  if (p2 == NULL) {
    /* p may be indeterminate when (size == 0). */ 
    free(p); 
    return;
  }
}

...

If the size of the space requested is zero, the behavior is implementation-defined: either a null pointer is returned, or the behavior is as if the size were some nonzero value, except that the returned pointer shall not be used to access an object.

And Section And subclause 7.22.3.5 states:

If memory for the new object cannot be allocated, the old object is not deallocated and its value is unchanged.

...

...