...
The C Standard, Annex J [ISO/IEC 9899:2011], states that the behavior
...
of a program is undefined when
The pointer argument to the
free
orrealloc
function does not match a pointer earlier returned by a memory management function, or the space has been deallocated by a call tofree
orrealloc
.
See also undefined behavior 179.
Freeing memory that is not allocated dynamically can result in heap corruption and other serious errors. Do not call free()
on anything a pointer other than a pointer one returned by a dynamic standard memory allocation function, such as malloc()
, calloc()
, realloc()
, or aligned_alloc()
.
A similar situation arises when realloc()
is supplied a pointer to non-dynamically allocated memory. The realloc()
function is used to resize a block of dynamic memory. If realloc()
is supplied a pointer to memory not allocated by a standard memory allocation function, such as malloc()
, the behavior is undefined. One consequence is that the program may terminate abnormally.
This rule does not apply to null pointers. The C Standard guarantees that if free()
is passed a null pointer, no action occurs.
...
Code Block | ||||
---|---|---|---|---|
| ||||
#include <stdlib.h> #include <string.h> #include <stdio.h> enum { MAX_ALLOCATION = 1000 }; int main(int argc, const char *argv[]) { char *c_str = NULL; size_t len; if (argc == 2) { len = strlen(argv[1]) + 1; if (len > MAX_ALLOCATION) { /* Handle error */ } c_str = (char *)malloc(len); if (c_str == NULL) { /* Handle error */ } strcpy(c_str, argv[1]); } else { printf("%s\n", "usage: $>a.exe [string]"); return -1EXIT_FAILURE; } free(c_str); return 0; } |
...
Code Block | ||||
---|---|---|---|---|
| ||||
#include <stdlib.h> enum { BUFSIZE = 256 }; void f(void) { char buf[BUFSIZE]; char *p = (char *)realloc(buf, 2 * BUFSIZE); if (p == NULL) { /* handleHandle error */ } } |
Compliant Solution (realloc()
)
...
Code Block | ||||
---|---|---|---|---|
| ||||
#include <stdlib.h> enum { BUFSIZE = 256 }; void f(void) { char *buf = (char *)malloc(BUFSIZE * sizeof(char)); char *p = (char *)realloc(buf, 2 * BUFSIZE); if (p == NULL) { /* handleHandle error */ } } |
Note that realloc()
will behave properly even if malloc()
failed, because when given a null pointer, realloc()
behaves like a call to malloc()
.
...
CERT C Secure Coding Standard | MEM31-C. Free dynamically allocated memory when no longer needed |
CERT C++ Secure Coding Standard | MEM34-CPP. Only free memory allocated dynamically |
ISO/IEC TS 17961 | Reallocating or freeing memory that was not dynamically allocated [xfree] |
MITRE CWE | CWE-590, Free of invalid pointer not Memory Not on the heapHeap |
Bibliography
...
[ISO/IEC 9899:2011] | Annex J, subclause J.2, "Undefined Behavior" |
[Seacord 2013b] | Chapter 4, "Dynamic Memory Management" |
...