CertC++-MEM31¶
Free dynamically allocated memory when no longer needed
Required inputs: IR, StaticSemanticAnalysis
Before the lifetime of the last pointer that stores the return value of a call
to a standard memory allocation function has ended, it must be matched by a
call to
free() with that pointer value.
Noncompliant Code Example
In this noncompliant example, the object allocated by the call to
malloc() is not freed before the end of the lifetime of the last
pointer
text_buffer referring to the object:
#include <stdlib.h>
enum { BUFFER_SIZE = 32 };
int f(void) {
char *text_buffer = (char *)malloc(BUFFER_SIZE);
if (text_buffer == NULL) {
return -1;
}
return 0;
}
Compliant Solution
In this compliant solution, the pointer is deallocated with a call
to
free():
#include <stdlib.h>
enum { BUFFER_SIZE = 32 };
int f(void) {
char *text_buffer = (char *)malloc(BUFFER_SIZE);
if (text_buffer == NULL) {
return -1;
}
free(text_buffer);
return 0;
}
Exceptions
MEM31-C-EX1: Allocated memory does not need to be freed if it
is assigned to a pointer whose lifetime includes program termination. The
following code example illustrates a pointer that stores the return value
from
malloc() in a
static variable:
#include <stdlib.h>
enum { BUFFER_SIZE = 32 };
int f(void) {
static char *text_buffer = NULL;
if (text_buffer == NULL) {
text_buffer = (char *)malloc(BUFFER_SIZE);
if (text_buffer == NULL) {
return -1;
}
}
return 0;
}
Risk Assessment
Failing to free memory can result in the exhaustion of system memory resources, which can lead to a denial-of-service attack.
| Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
|---|---|---|---|---|---|
| MEM31-C | Medium | Probable | Medium | P8 | L2 |
Related Guidelines
| Taxonomy | Taxonomy item | Relationship |
|---|---|---|
| ISO/IEC TR 24772:2013 | Memory Leak [XYL] | Prior to 2018-01-12: CERT: Unspecified Relationship |
| ISO/IEC TS 17961 | Failing to close files or free dynamic memory when they are no longer needed [fileclose] | Prior to 2018-01-12: CERT: Unspecified Relationship |
| CWE 2.11 | CWE-401, Improper Release of Memory Before Removing Last Reference ("Memory Leak") | 2017-07-05: CERT: Exact |
| CWE 2.11 | CWE-404 | 2017-07-06: CERT: Rule subset of CWE |
| CWE 2.11 | CWE-459 | 2017-07-06: CERT: Rule subset of CWE |
| CWE 2.11 | CWE-771 | 2017-07-06: CERT: Rule subset of CWE |
| CWE 2.11 | CWE-772 | 2017-07-06: CERT: Rule subset of CWE |
Bibliography
| [ ISO/IEC 9899:2011] | Subclause 7.22.3, "Memory Management Functions" |
Possible Messages
Key |
Text |
Severity |
Disabled |
|---|---|---|---|
memory_leak |
Call allocates leaking memory |
None |
False |
possible_memory_leak |
Call allocates possibly leaking memory |
None |
False |
Options¶
This rule shares the following common options: exclude_in_macros, exclude_messages_in_system_headers, excludes, extend_exclude_to_macro_invocations, includes, justification_checker, languages, post_processing, provider, report_at, severity
The following places define options that affect this rule: Stylechecks, Analysis-GlobalOptions
resources¶
resources
Set of resources to be checked (selection of rules in the Resources group).Type: set[str]
Default:
{'C++HeapMemory', 'CudaAsyncMemory', 'CudaDeviceMemory', 'CudaDriverAsyncMemory', 'CudaHostMemory', 'CudaManagedMemory', 'HeapMemory', 'UniquePtrHeapMemory'}
witness_paths¶
witness_paths : bool = True
witness_should_include_exception_handling¶
witness_should_include_exception_handling : bool = False