Acest curs explică organizarea memoriei într-un program C, detaliind segmentele Stack, Heap, Data și Text.
Atunci când un program scris în C rulează, memoria este împărțită în mai multe segmente, fiecare având un scop specific.
Source: https://www.geeksforgeeks.org/memory-layout-of-c-program/
- Text Segment: Conține codul binar executabil al programului.
- Data Segment: Conține variabile globale și statice inițializate.
- BSS Segment: Conține variabile globale/statice neinițializate (valori default 0).
- Heap Segment: Memorie alocată dinamic (ex: malloc, calloc, realloc).
- Stack Segment: Memorie utilizată pentru variabile locale și apeluri recursive.
Segmentul de text conține codul executabil al programului. Acesta este de obicei protejat împotriva scrierii pentru a preveni modificările accidentale ale codului la runtime.
int main() {
printf("Hello, world!\n");
return 0;
}
În acest exemplu, instrucțiunile `printf` și `return` sunt plasate în segmentul de text.
Segmentul de date conține variabile globale și statice care sunt inițializate explicit înainte de execuție.
int global_var = 10;
static int static_var = 5;
int main() {
return 0;
}
Aici, `global_var` și `static_var` sunt plasate în segmentul Data deoarece sunt inițializate.
Segmentul BSS conține variabile globale și statice care nu au fost inițializate explicit și primesc implicit valoarea `0`.
int uninitialized_global;
static int uninitialized_static;
int main() {
return 0;
}
Aici, `uninitialized_global` și `uninitialized_static` vor fi plasate în segmentul BSS și vor avea valoarea `0`.
Heap-ul este utilizat pentru alocări dinamice de memorie și crește sau scade în funcție de necesitățile programului.
#include <stdlib.h>
int main() {
int *ptr = malloc(10 * sizeof(int));
if (ptr) {
ptr[0] = 42;
free(ptr);
}
return 0;
}
Memoria alocată dinamic cu `malloc` provine din segmentul Heap și trebuie eliberată manual cu `free` pentru a preveni memory leaks.
Stack-ul este utilizat pentru stocarea variabilelor locale și gestionarea apelurilor de funcții recursive.
void recursive_function(int count) {
int local_var = count;
if (count > 0) {
recursive_function(count - 1);
}
}
int main() {
recursive_function(3);
return 0;
}
Fiecare apel recursiv creează un nou cadru de stivă pentru variabila `local_var`, ceea ce poate duce la Stack Overflow dacă recursivitatea este prea adâncă.
Poți verifica segmentele de memorie ale unui program folosind `size` și `/proc/self/maps` pe Linux.
gcc -o program program.c
size program
cat /proc/self/maps