Terve taas,
olen pohtinut, kuinka C:llä toteutetaan muistinlisäys muuttujalle, jolle on jo kerran jaettu malloc-funktion avulla muistia. Eli näin:
int i, *m = NULL; m = malloc(50 * sizeof(int)); for (i = 0; i < 50; i++) { m[i] = i; } m = malloc(70 * sizeof(int)); // Näin se EI onnistu, mutta tästä näkee, mitä haen takaa for (i = 50; i < 70; i++) { m[i] = i; } free(m);
Kävin jo pari vaihtoehtoa mielessäni läpi, mutta paras niistä kuuluisi näin:
// Muisti on varattu jne. int *tmp = NULL; tmp = malloc(50 * sizeof(int)); for (i = 0; i < 50; i++) { tmp[i] = m[i]; } free(m); m = malloc(70 * sizeof(int)); for (i = 0; i < 50; i++) { m[i] = tmp[i]; } for (i = 50; i < 70; i++) { m[i] = i; } free(tmp);
...joka ei kuitenkaan ei tunnu siltä parhaalta vaihtoehdolta. Ehdotuksia?
Funktio realloc muuttaa aiemmin varatun muistialueen kokoa.
No sepä kävi näppärästi! Kiitos kovasti. :)
Kannattaa muistaa, että vaikka realloc säilyttääkin muistissa olevan datan, sen palauttama osoitin ei välttämättä ole sama kuin ennen (esimerkiksi jos kyseiseen muistikohtaan ei mahdu vaadittua palasta). Seuraavassa ohjelmassa saattaa siis tapahtua virhe:
char *muisti, *kopio; muisti = malloc(10); kopio = muisti; muisti = realloc(muisti, 20); kopio[0] = 'a'; // Virhe! Voi olla, että kopio[0] osuukin nyt jo vapautettuun kohtaan. free(muisti);
Jos ohjelman on tarkoitus selvitä myös siitä virhetapauksesta, että muistin varaaminen epäonnistuu, vanha osoitin on hyvä ottaa talteen ennen kutsua:
void *ptr = malloc(koko_a); void *tmp; tmp = realloc(ptr, koko_b); if (!tmp) { // Pieleen meni, mutta vanha alue säilyy silti. printf("Virhe varauksessa! Varattua tilaa ei muutettu."); } else { // Varaus onnistui, otetaan uusi osoite käyttöön ptr = tmp; } free(ptr);
Aihe on jo aika vanha, joten et voi enää vastata siihen.