Mastering C Memory Leak Prevention: Principles, Common Pitfalls, and Review Techniques
This article explains how memory leaks occur in C programs, outlines the three essential elements of a leak, clarifies common misconceptions about freeing heap memory, and provides a practical code‑review checklist to detect and prevent leaks before deployment.
1. Introduction
Memory leaks in embedded products cause board resets after months of operation because heap memory is exhausted. A leak occurs when heap‑allocated memory is not released before the allocating function exits or when ownership is not transferred. This summary describes the principles of heap memory in C, the two common patterns for obtaining heap memory, the three elements that constitute a leak, common misconceptions about freeing, and a systematic inspection checklist.
2. Heap Memory and Leak Mechanisms
2.1 Heap allocation in C
Only heap memory can leak; stack memory is automatically reclaimed. In C the standard allocator is malloc; many projects wrap it (e.g., g_malloc, VOS_Malloc). The allocator returns a pointer that must be stored in a variable of pointer type (single‑level or multi‑level).
char *info = NULL;
/* convert string */
info = (char *)malloc(NB_MEM_SPD_INFO_MAX_SIZE);
if (info == NULL) {
(void)tdm_error("malloc error!
");
return NB_SA_ERR_HPI_OUT_OF_MEMORY;
}2.2 Two common ways to obtain heap memory
Assign the function’s return value directly to a pointer.
char *local_pointer_xx = NULL;
local_pointer_xx = (char *)function_xx(param1, ...);Typical APIs such as GSList* g_slist_append(GSList *list, gpointer data) follow this pattern.
Pass a pointer‑to‑pointer as an output parameter.
int ret;
char *local_pointer_xx = NULL;
/* convert string */
ret = function_xx(..., &local_pointer_xx, ...);Functions like getline(char **lineptr, size_t *n, FILE *stream) use this pattern. In both cases the callee allocates memory and returns the address either via the return value or an output parameter.
2.3 Three essential elements of a memory leak
A local pointer variable is declared inside a function.
The pointer receives heap memory through one of the two acquisition patterns.
The allocated memory is neither freed nor transferred (e.g., stored in a global variable or returned) before every exit path of the function.
2.4 Common misconceptions about freeing memory
Developers often assume that only memory obtained directly from malloc (or its wrappers) needs to be freed, or that they must free memory only when using familiar APIs. This leads to missed releases for allocations performed by less‑known interfaces, for example:
dfl_get_object_list(const char *class_name, GSList **list);If the function allocates a list, the caller must free it even though the allocation is hidden inside the API.
3. Inspection Methodology
During code review, treat every local pointer as a potential leak and verify the three elements above.
Identify the declaration of a local pointer.
Determine whether the pointer was obtained via a return‑value assignment or an output‑parameter call. Consult the API documentation or source to locate the corresponding release function.
Confirm that every control‑flow path (normal return, error return, early exit) either frees the memory or transfers ownership appropriately.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Liangxu Linux
Liangxu, a self‑taught IT professional now working as a Linux development engineer at a Fortune 500 multinational, shares extensive Linux knowledge—fundamentals, applications, tools, plus Git, databases, Raspberry Pi, etc. (Reply “Linux” to receive essential resources.)
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
