...
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;
}
|
...