Ce face realloc
realloc mărește sau micșorează un bloc obținut cu malloc, calloc sau realloc. Datele existente (până la minimul dintre vechea și noua dimensiune) sunt păstrate. Partea nouă, când blocul crește, nu este inițializată.
Dacă nu există loc imediat după bloc, realloc alocă unul nou, copiază datele, eliberează blocul vechi și returnează noua adresă. De aceea folosești mereu pointerul returnat, nu pe cel vechi.
Dacă alocarea eșuează, returnează NULL, iar blocul vechi rămâne valid și neatins. Din acest motiv nu scrie p = realloc(p, ...): la eșec ai pierde singura adresă a blocului. Folosește un pointer temporar. realloc(NULL, n) se comportă ca malloc(n).
Parametri
| Parametru | Descriere |
|---|---|
ptr |
Blocul existent (sau NULL, caz în care funcția se comportă ca malloc). |
new_size |
Noua dimensiune în octeți. Din C23, valoarea 0 dă comportament nedefinit: pentru eliberare folosește free. |
Ce returnează
Pointerul spre blocul redimensionat (poate fi altă adresă) sau NULL dacă nu s-a putut, caz în care ptr rămâne valid.
Exemple
Exemplul 1: Un tablou care crește după nevoie
Capacitatea se dublează când se umple. Rezultatul lui realloc merge într-un pointer temporar, ca blocul vechi să nu se piardă dacă alocarea eșuează.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
size_t capacitate = 2, n = 0;
int *cheltuieli = malloc(capacitate * sizeof *cheltuieli);
if (cheltuieli == NULL) return 0;
int valoare;
while (scanf("%d", &valoare) == 1) {
if (n == capacitate) {
int *nou = realloc(cheltuieli, 2 * capacitate * sizeof *nou);
if (nou == NULL) break; // blocul vechi este încă valid
cheltuieli = nou;
capacitate *= 2;
printf("capacitate mărită la %zu\n", capacitate);
}
cheltuieli[n++] = valoare;
}
int total = 0;
for (size_t i = 0; i < n; i++) total += cheltuieli[i];
printf("%zu cheltuieli, total %d lei\n", n, total);
free(cheltuieli);
return 0;
}
Ce scrie utilizatorul (intrare)
120 45 300 80 15 60
Rezultat
capacitate mărită la 4
capacitate mărită la 8
6 cheltuieli, total 620 lei
Exemplul 2: Un șir la care se adaugă text
La fiecare adăugare se cere exact cât trebuie: lungimea actuală, textul nou și '\0'.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int adauga(char **s, const char *text) {
size_t vechi = *s ? strlen(*s) : 0;
char *nou = realloc(*s, vechi + strlen(text) + 1);
if (nou == NULL) return 0;
strcpy(nou + vechi, text);
*s = nou;
return 1;
}
int main(void) {
char *traseu = NULL; // realloc(NULL, n) = malloc(n)
const char *orase[] = {"Iași", " - Bacău", " - Brașov", " - București"};
for (size_t i = 0; i < 4; i++) {
if (!adauga(&traseu, orase[i])) break;
}
printf("%s\n", traseu);
free(traseu);
return 0;
}
Rezultat
Iași - Bacău - Brașov - București
Exemplul 3: Micșorarea unui bloc
După ce știi câte elemente ai păstrat, poți micșora blocul. Primele elemente rămân neschimbate.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int *v = malloc(100 * sizeof *v);
if (v == NULL) return 0;
size_t n = 0;
for (int i = 1; i <= 100; i++) {
if (i % 30 == 0) v[n++] = i; // păstrăm doar multiplii lui 30
}
int *mic = realloc(v, n * sizeof *mic);
if (mic != NULL) v = mic;
for (size_t i = 0; i < n; i++) printf("%d ", v[i]);
printf("\n");
free(v);
return 0;
}
Rezultat
30 60 90
Greșeli frecvente
- Scrii
p = realloc(p, n);. Dacărealloceșuează,pdevineNULL, iar blocul vechi rămâne alocat fără ca cineva să-i mai știe adresa. - Folosești în continuare pointerul vechi după un
reallocreușit. Blocul s-ar putea să fi fost mutat și eliberat; pointerul vechi nu mai este valid. - Păstrezi pointeri spre interiorul blocului (de exemplu spre al treilea element) și apoi îl redimensionezi. Și ei devin invalizi dacă blocul se mută.
- Mărești cu câte un element la fiecare adăugare. Fiecare apel poate copia tot blocul; crește capacitatea în pași mari (de exemplu dublare).
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.free: Eliberează un bloc alocat cu malloc, calloc sau realloc, ca memoria să poată fi refolosită.Pointer la pointer (**): Un pointer care păstrează adresa altui pointer: util când o funcție trebuie să schimbe un pointer sau pentru tablouri de șiruri.strcat și strncat: Lipește un șir la sfârșitul altui șir aflat într-un tablou destul de mare.
Întrebări & Exemple de Cod:
reallocAi o nelămurire despre utilizarea comenzii
reallocsau 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.