...
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 | ||||
---|---|---|---|---|
| ||||
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 | ||||
---|---|---|---|---|
| ||||
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 | ||||
---|---|---|---|---|
| ||||
/* 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 | ||||
---|---|---|---|---|
| ||||
/* p is a pointer to dynamically allocated memory */ if (size) { p2 = realloc(p, size); if (p2 == NULL) { free(p); return; } } else { free(p); return; } |
...