realloc în C

Schimbă dimensiunea unui bloc alocat dinamic, păstrând conținutul; poate muta blocul la altă adresă.

Sintaxă
#include <stdlib.h>
void *realloc(void *ptr, size_t new_size);

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ă realloc eșuează, p devine NULL, iar blocul vechi rămâne alocat fără ca cineva să-i mai știe adresa.
  • Folosești în continuare pointerul vechi după un realloc reuș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.
Comunitate & Schimb de cunoștințe

Întrebări & Exemple de Cod: realloc

Ai o nelămurire despre utilizarea comenzii realloc sau 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.

Comunitate Adaugă o întrebare sau distribuie un cod

Moderare & Siguranță:

Pentru a menține calitatea și securitatea informațiilor, fiecare întrebare sau fragment de cod/prompt este analizat (manual sau prin moderare asistată de AI) înainte de publicare.