Freeing memory that is not allocated dynamically can lead to serious errors. The specific consequences of this error depends on the compiler, but ranges from nothing to abnormal program termination. Regardless of the compiler, avoid calling free()
on non-dynamic memory.
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 memory allocation function, such as{{malloc()}}, the program may also terminate abnormally.
Non-compliant Code Example 1
The following piece of code validates the number of command line arguemnts. If the correct number of commmand line arguements have been specified, memory is allocated with malloc()
and referenced by str
. Next, the second command line argument is copied into str
for further processing. Once this processing is complete, str
is freed.However, if the incorrect number of arguments have been specified, str
is set to a string literal and printed. Because str
now references memory that was not dynamically allocated, an error will occur when str
memory is freed.
int main(int argc, char *argv[]) { char *str = NULL; if (argc == 2) { str = malloc(strlen(argv[1])); if (str == NULL) { /* Handle Allocation Error */ } strcpy(str,argv[1]); } else { str = "usage: $>a.exe [string]"; printf("%s\n", str); } /* ... */ free(str); return 0; }
Compliant Solution 1
In the compliant solution, theprogram has been changed to eliminate the possibility of str
referencing non-dynamic memory and when it is supplied to free()
.
int main(int argc, char *argv[]) { char *str = NULL; if (argc == 2) { str = malloc(strlen(argv[1])); if (str == NULL) { /* Handle Allocation Error */ } strcpy(str,argv[1]); } else { printf("usage: $>a.exe [string]\n"); return 1; } /* ... */ free(str); return 0; }