Background:
Dynamic memory allocation mechanisms were introduced in C along with the standard library functions malloc/free in <stdlib.h>. They enabled the implementation of variable-size structures, complex collections, and objects, providing a powerful impetus for the development of the language and its use in large programming.
Issue:
Working with dynamic memory requires the programmer to have complete control over the lifecycle of objects. Mistakes (memory leaks, double free, improper pointer use) can lead to crashes or vulnerabilities (for example, exploits via use-after-free errors).
Solution:
— Always check the return values of malloc/calloc/realloc. If allocation fails, they return NULL. — After freeing memory, set the pointer to NULL to avoid using the freed block. — Do not use the pointer after free. — Maintain correct correspondence between malloc/free and calloc/free.
Example code:
#include <stdio.h> #include <stdlib.h> int main() { int *arr = malloc(5 * sizeof(int)); if (!arr) { perror("Memory allocation failed"); return 1; } for (int i = 0; i < 5; ++i) arr[i] = i * i; for (int i = 0; i < 5; ++i) printf("%d ", arr[i]); printf(" "); free(arr); arr = NULL; return 0; }
Key features:
What happens if you free memory allocated with malloc using the delete operator or vice versa (in C++)?
You cannot mix memory allocation and deallocation mechanisms between languages (C/C++). In C — only malloc/free, in C++ — new/delete.
What happens when attempting to call free(NULL)?
free(NULL) is safe (this is guaranteed by the C standard). Such a call does nothing.
Can realloc be used to increase or decrease a block of memory, and what happens to the original pointer?
realloc may move the memory block, and if this happens, the old pointer becomes invalid. Always assign the new pointer:
ptr = realloc(ptr, new_size);
Memory was allocated for an array in a loop, but it was forgotten to be freed at the end of the iteration. Overnight, the program "consumed" all RAM on the server.
Pros:
Cons:
Memory was always freed after use in the loop, all NULL checks were performed immediately after malloc, and debugging tools were used to monitor leaks.
Pros:
Cons: