...
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 | ||||
---|---|---|---|---|
| ||||
#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 | ||||
---|---|---|---|---|
| ||||
#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.
...
CERT C Secure Coding Standard | MEM01-C. Store a new value in pointers immediately after free() MEM04-C. Do not perform zero-length allocations INT32-C. Ensure that operations on signed integers do not result in overflow |
CERT C++ Secure Coding Standard | MEM31-CPP. Free dynamically allocated memory exactly once |
ISO/IEC TR 24772:2013 | Dangling Reference to Heap [XYK] Memory Leak [XYL] |
ISO/IEC TS 17961 (Draft) | Freeing memory multiple times [dblfree] |
MITRE CWE | CWE-415, Double free |
...