Kasvattaminen reallocilla
Muuttakaa dynaamisen taulukon kokoa.
Kasvattaminen reallocilla on ilmainen C Academy-oppitunti CoddyKitissä. Tämä on oppitunti 2/4. Voit lukea koko oppitunnin alta ilmaiseksi ja harjoitella sen jälkeen käytännössä selaimessa sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla. Oppitunti kuuluu C Academy-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. C Academy-kurssilla on yhteensä 4 oppituntia.
Kun yksi malloc ei riitä
Joskus varaatte taulukon, täytätte sen ja huomaatte sitten tarvitsevänne lisää tilaa. Taulukon lopun yli ei voi vain kirjoittaa.
realloc mahdollistaa olemassa olevan kekomuistilohkon koon muuttamisen ja säilyttää siinä jo olevat tiedot.
realloc-funktion allekirjoitus
realloc(ptr, new_bytes) saa argumenteikseen vanhan osoittimen ja uuden kokonaiskoon tavuina.
Se palauttaa uuden koon mukaisen lohkon osoittimen. Tietojen alkuosa säilyy vanhan ja uuden koon pienempään arvoon asti.
int *bigger = realloc(a, new_n * sizeof(*a));Lohko voi siirtyä
realloc voi kasvattaa lohkoa paikallaan tai varata uuden lohkon, kopioida tiedot siihen ja vapauttaa vanhan lohkon.
Joka tapauksessa vanha osoitin saattaa muuttua virheelliseksi. Käyttäkää tästä lähtien palautettua osoitinta.
a = realloc(a, new_n * sizeof(*a));
/* the old value of a may no longer be valid */Itseensä sijoittamisen sudenkuoppa
a = realloc(a, ...) näyttää siistiltä mutta on vaarallinen: jos realloc palauttaa NULL-arvon, olette korvanneet muuttujan a arvon ja menettäneet alkuperäisen osoittimen, jolloin vanha lohko jää vapauttamatta.
Käyttäkää sen sijaan väliaikaista muuttujaa.
int *tmp = realloc(a, new_n * sizeof(*a));
if (tmp == NULL) { /* a is still valid */ return 1; }
a = tmp;Taulukon turvallinen kasvattaminen
Tämä ohjelma varaa tilan kolmelle int-alkiolle ja kasvattaa taulukon reallocilla kuuteen säilyttäen kolme ensimmäistä arvoa.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int *a = malloc(3 * sizeof(*a));
if (!a) return 1;
for (int i = 0; i < 3; i++) a[i] = i + 1;
int *tmp = realloc(a, 6 * sizeof(*a));
if (!tmp) { free(a); return 1; }
a = tmp;
for (int i = 3; i < 6; i++) a[i] = i + 1;
for (int i = 0; i < 6; i++) printf("%d\n", a[i]);
free(a);
return 0;
}Uudet tavut ovat alustamattomia
Kun kasvatatte lohkoa, sen lopussa oleva ylimääräinen tila sisältää roskaa aivan kuten uusi malloc-muisti.
realloc säilyttää vanhat tiedot, mutta ei nollaa uutta aluetta. Alustakaa se ennen lukemista.
a = realloc(a, 6 * sizeof(*a));
for (int i = 3; i < 6; i++) a[i] = 0; /* clear new slots */Kaksinkertaistamisstrategia
realloc-funktion kutsuminen jokaisen yksittäisen alkion kohdalla on hidasta. Tavallinen keino on kaksinkertaistaa kapasiteetti aina, kun tila loppuu.
Näin uudelleenvarausten määrä pysyy pienenä taulukon kasvaessa, mikä antaa hyvän keskimääräisen suorituskyvyn.
if (count == cap) {
cap = cap ? cap * 2 : 4;
int *tmp = realloc(a, cap * sizeof(*a));
if (!tmp) { free(a); return 1; }
a = tmp;
}Taulukon rakentaminen lisäämällä loppuun
Tämä ohjelma aloittaa tyhjänä ja lisää lukuja loppuun kaksinkertaistaen kapasiteettia tarpeen mukaan.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int *a = NULL;
size_t count = 0, cap = 0;
for (int v = 1; v <= 5; v++) {
if (count == cap) {
cap = cap ? cap * 2 : 2;
int *tmp = realloc(a, cap * sizeof(*a));
if (!tmp) { free(a); return 1; }
a = tmp;
}
a[count++] = v;
}
for (size_t i = 0; i < count; i++) printf("%d\n", a[i]);
free(a);
return 0;
}realloc(NULL, n) toimii kuten malloc
Jos välitätte osoittimeksi NULL, realloc toimii täsmälleen kuten malloc.
Siksi silmukan aloittaminen komennolla a = NULL toimii kaksinkertaistusratkaisussa: ensimmäinen realloc varaa alkuperäisen lohkon.
int *a = NULL;
a = realloc(a, 4 * sizeof(*a)); /* same as malloc(4 * sizeof(*a)) */Lohkon pienentäminen
realloc voi myös pienentää lohkoa. Uuteen kokoon asti olevat tiedot säilyvät ja loppuosa hylätään.
Pienentäminen voi vapauttaa muistia, mutta toteutukset voivat halutessaan pitää suuremman lohkon varattuna.
int *tmp = realloc(a, 2 * sizeof(*a)); /* down from more */
if (tmp) a = tmp;Ylivuodon välttäminen laskutoimituksessa
Kapasiteetin kasvaessa suureksi cap * sizeof(*a) voi aiheuttaa size_t-tyypin ylivuodon ja muuttua silmukalla hyvin pieneksi luvuksi.
Suurten taulukoiden tapauksessa varmistakaa kertolasku ylivuodon varalta tai käyttäkää reallocarray-funktiota järjestelmissä, joissa se on saatavilla.
if (cap > SIZE_MAX / sizeof(*a)) { /* overflow */ return 1; }
int *tmp = realloc(a, cap * sizeof(*a));Pikatarkistus
Testatkaa, miten hyvin ymmärrätte realloc-funktion.
Kertaus
realloc muuttaa keokeomuistilohkon kokoa ja saattaa siirtää sen, joten käyttäkää aina palautettua osoitinta.
Sijoittakaa tulos väliaikaiseen muuttujaan, jotta alkuperäinen osoitin ei katoa epäonnistumisen yhteydessä. Kasvattakaa kapasiteettia nopeuden vuoksi kaksinkertaiseksi, alustakaa uudet alkiot ja muistakaa, että realloc(NULL, n) vastaa malloc-kutsua. Seuraavaksi paketoitte tämän logiikan uudelleenkäytettäväksi vektorityypiksi.
Opi C tekoälytuutorin avulla — ilmaiseksi
Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.
- Kurssit
- 39
- Oppitunnit
- 144
Usein kysytyt kysymykset
Onko oppitunti ”Kasvattaminen reallocilla” ilmainen?
Kyllä – oppitunnin ”Kasvattaminen reallocilla” koko tekstin voi lukea täällä verkossa ilmaiseksi. Jos haluat harjoitella interaktiivisesti sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla sekä avata koko C Academy-kurssin, päivitä CoddyKit PROhon. C Academy-kurssilla on yhteensä 4 oppituntia.
Mitä opin oppitunnilla ”Kasvattaminen reallocilla”?
Muuttakaa dynaamisen taulukon kokoa. Harjoittelet C Academy-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.
Tarvitsenko kokemusta aloittaakseni C Academy-opiskelun?
Aiempi kokemus ei ole tarpeen. CoddyKitin C Academy-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 2/4.
Kuinka kauan ”Kasvattaminen reallocilla”-oppitunnin suorittaminen kestää?
Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.
Voinko kirjoittaa ja suorittaa koodia tällä C Academy-oppitunnilla?
Kyllä. Jokainen C Academy-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.
Kaikki tämän kurssin oppitunnit
- Taulukon varaaminen
- Kasvattaminen reallocilla
- Uudelleenkäytettävä vektorityyppi
- Vapauttaminen ja vuotojen välttäminen