ProgrammingBackend C developer

Discuss in detail dynamic memory allocation, usage, and correct deallocation in C using malloc/free. What pitfalls exist when working with dynamic memory?

Pass interviews with Hintsage AI assistant

Answer.

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:

  • malloc/calloc/realloc return void* and require explicit type casting (not for C, for C++).
  • After free, the pointer becomes invalid.
  • The size of the allocated memory always depends on the type and number of elements (n * sizeof(type)).

Trick questions.

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);

Common mistakes and anti-patterns

  • Using memory after free (use-after-free).
  • Double free calls for the same pointer.
  • Memory leaks (allocated — not freed).
  • Errors in calculating memory size during malloc (forgot sizeof(...)).
  • Ignoring the NULL return on unsuccessful malloc.

Real-life example

Negative case

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:

  • Code is simpler, fewer checks.

Cons:

  • Memory leak, reduced performance, application crash.

Positive case

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:

  • Stable operation, no leaks.
  • Code is easy to maintain and scale.

Cons:

  • Slightly more verbose code, requires attention at every stage of memory lifecycle.