Ce face free
free întoarce sistemului memoria primită de la malloc, calloc sau realloc. După apel, blocul nu mai este al tău: pointerul păstrează aceeași adresă, dar folosirea lui este comportament nedefinit (pointer „atârnat”, dangling pointer).
Fiecare alocare trebuie eliberată exact o dată. free(NULL) este permis și nu face nimic, de aceea un obicei bun este să pui pointerul pe NULL imediat după free: o a doua eliberare devine inofensivă, iar o folosire greșită se vede mai ușor.
Pentru structuri care conțin pointeri spre alte blocuri, eliberează întâi blocurile interioare, apoi structura. Nu chema free pe adrese care nu vin de la alocare (variabile locale, literali, mijlocul unui bloc).
Parametri
| Parametru | Descriere |
|---|---|
ptr |
Pointerul primit de la o funcție de alocare sau NULL. |
Ce returnează
Nimic (void).
Exemple
Exemplul 1: Eliberare și punere pe NULL
După free, pointerul este pus pe NULL. Al doilea free primește NULL și nu face nimic.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
double *preturi = malloc(3 * sizeof *preturi);
if (preturi == NULL) return 0;
preturi[0] = 4.5; preturi[1] = 12.0; preturi[2] = 7.25;
printf("primul preț: %.2f lei\n", preturi[0]);
free(preturi);
preturi = NULL;
free(preturi); // free(NULL): fără efect
printf("pointer: %s\n", preturi == NULL ? "NULL" : "adresă");
return 0;
}
Rezultat
primul preț: 4.50 lei
pointer: NULL
Exemplul 2: Eliberarea unei structuri cu memorie interioară
Structura are un tablou alocat separat. Funcția de distrugere eliberează întâi tabloul, apoi structura.
#include <stdio.h>
#include <stdlib.h>
typedef struct {
size_t n;
int *note;
} Catalog;
Catalog *catalog_nou(size_t n) {
Catalog *c = malloc(sizeof *c);
if (c == NULL) return NULL;
c->note = calloc(n, sizeof *c->note);
if (c->note == NULL) {
free(c);
return NULL;
}
c->n = n;
return c;
}
void catalog_sterge(Catalog *c) {
if (c == NULL) return;
free(c->note); // întâi memoria interioară
free(c); // apoi structura
}
int main(void) {
Catalog *c = catalog_nou(25);
if (c != NULL) {
c->note[0] = 10;
printf("catalog cu %zu locuri, prima notă %d\n", c->n, c->note[0]);
}
catalog_sterge(c);
return 0;
}
Rezultat
catalog cu 25 locuri, prima notă 10
Exemplul 3: Folosire după free (nu rula așa)
Codul citește din blocul deja eliberat. Pe calculatorul de test a afișat 4, nu 500: memoria fusese deja refolosită. Poate afișa și vechea valoare sau se poate opri; cu -fsanitize=address, programul se oprește cu „heap-use-after-free”.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int *sold = malloc(sizeof *sold);
if (sold == NULL) return 0;
*sold = 500;
free(sold);
printf("%d\n", *sold); // GREȘIT: blocul nu mai este al nostru
return 0;
}
Rezultat posibil (comportament nedefinit)
4
Greșeli frecvente
- Eliberezi de două ori același bloc (double free). Este comportament nedefinit și poate strica administrarea memoriei. Pune pointerul pe
NULLdupăfree. - Folosești memoria după
free. Programul poate părea că merge, apoi dă rezultate greșite mai târziu; compilează cu-fsanitize=addressîn timpul dezvoltării ca să prinzi astfel de erori. - Chemi
freepe o variabilă locală, pe un literal sau pep + 1. Doar adresele exacte returnate de funcțiile de alocare pot fi eliberate. - Eliberezi structura înaintea memoriei interioare. După
free(c),c->notenu mai poate fi citit, așa că tabloul rămâne alocat pentru totdeauna.
Comenzi înrudite
malloc: Cere sistemului un bloc de memorie de mărimea dată, în timpul rulării, și returnează adresa lui sau NULL dacă nu reușește.calloc: Alocă memorie pentru un tablou de count elemente a câte size octeți și pune zero în toți octeții.realloc: Schimbă dimensiunea unui bloc alocat dinamic, păstrând conținutul; poate muta blocul la altă adresă.Comportament nedefinit (undefined behavior): Situațiile pentru care standardul C nu spune ce se întâmplă: programul poate merge, poate da rezultate greșite sau se poate opri.Pointeri (& și *): O variabilă care păstrează adresa altei variabile; cu * citești sau modifici valoarea de la acea adresă.
Întrebări & Exemple de Cod:
freeAi o nelămurire despre utilizarea comenzii
freesau ai descoperit un truc / fragment de cod util? Distribuie-l cu ceilalți programatori!Fii primul care pune o întrebare sau distribuie un fragment de cod / prompt!
Nu au fost adăugate încă întrebări sau exemple de cod pentru această pagină. Dacă ai întâlnit o problemă sau ai un snippet util, adaugă-l mai jos pentru a-i ajuta pe ceilalți.