Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Oppiskele Malloc ja Free | Osoittimet
C:n Perusteet

bookMalloc ja Free

Nämä funktiot mahdollistavat uusien olioiden luomisen ei käännösvaiheessa, vaan ohjelman suorituksen aikana, jolloin voidaan käyttää dynaamista muistinvarausta.

malloc()

Aiemmin muistin varaaminen tiedoille tapahtui yksinkertaisesti määrittelemällä:

int x;

Nyt malloc()-funktion avulla muisti voidaan varata dynaamisesti:

int* pX = (int*)malloc(4);

malloc()-funktio vaatii argumenttina varattavien tavujen määrän. Jos et tiedä tarvittavaa tavumäärää, mutta tiedät tallennettavan tietotyypin, voit muuttaa lauseketta näin:

int* pX = (int*)malloc(sizeof(int));

Mitä seuraavaksi? Huomaa, että sijoitamme malloc()-funktion tuloksen osoittimeen. Tämä tarkoittaa, että malloc() palauttaa osoitteen!

Etuliite (int*) on eksplisiittinen tyyppimuunnos. Määrittelemme halutun tyypin itse. Esimerkiksi:

double x = 3.14;
int y = (int)x;   // `y` = 3
Main.c

Main.c

copy
1234567891011
#include <stdio.h> #include <stdlib.h> // new header file! int main() { int* pX = (int*)malloc(sizeof(int)); printf("Address of allocated memory: %p\n", pX); return 0; }

Huom

Muista sisällyttää otsikkotiedosto stdlib.h. Se sisältää malloc()-funktion prototyypin.

Tallentaaksemme tietoa osoitteeseen, jonka malloc()-funktio palauttaa, käytämme osoitteen purku -operaattoria.

Main.c

Main.c

copy
123456789101112
#include <stdio.h> #include <stdlib.h> int main() { int* pX = (int*)malloc(sizeof(int)); *pX = 100; printf(" Value %d at address %p\n", *pX, pX); return 0; }

Onko mahdollista vapauttaa muistia? – Kyllä, mutta vain malloc()- ja vastaavien funktioiden varaama muisti voidaan vapauttaa.

free()

Tätä funktiota käytetään osoittimien kanssa. Havainnollistetaan asiaa laajentamalla yllä olevaa esimerkkiä:

Main.c

Main.c

copy
1234567891011121314151617
#include <stdio.h> #include <stdlib.h> int main() { int* pX = (int*)malloc(sizeof(int)); *pX = 100; printf(" Value %d at address %p\n", *pX, pX); free(pX); printf("After `free()` value %d at address %p\n", *pX, pX); return 0; }

On mielenkiintoista, että vaikka osoitin "poistetaan", se säilyy toiminnallisena, mutta siihen liittyvän muistipaikan arvo muuttuu epäluotettavaksi.

Tämä aiheuttaa ongelman: varattu muistisolun sisältö on nyt epäluotettavaa tietoa. Tällaisen tilanteen estämiseksi käytetty osoitin tulisi asettaa arvoon NULL.

Main.c

Main.c

copy
1234567891011121314151617
#include <stdio.h> #include <stdlib.h> int main() { int* pX = (int*)malloc(sizeof(int)); *pX = 100; printf("Value %d at address %p\n", *pX, pX); free(pX); pX = NULL; return 0; }

Osoittimen asettaminen arvoon NULL vapauttamisen jälkeen on selkeä tapa osoittaa, ettei osoitin enää viittaa kelvolliseen muistipaikkaan.

Tarkista aina, onko osoitin NULL ennen sen käyttöä varmistaaksesi, ettet käytä virheellistä tai jo varattua muistia.

Oliko kaikki selvää?

Miten voimme parantaa sitä?

Kiitos palautteestasi!

Osio 6. Luku 4

Kysy tekoälyä

expand

Kysy tekoälyä

ChatGPT

Kysy mitä tahansa tai kokeile jotakin ehdotetuista kysymyksistä aloittaaksesi keskustelumme

Awesome!

Completion rate improved to 2.63

bookMalloc ja Free

Pyyhkäise näyttääksesi valikon

Nämä funktiot mahdollistavat uusien olioiden luomisen ei käännösvaiheessa, vaan ohjelman suorituksen aikana, jolloin voidaan käyttää dynaamista muistinvarausta.

malloc()

Aiemmin muistin varaaminen tiedoille tapahtui yksinkertaisesti määrittelemällä:

int x;

Nyt malloc()-funktion avulla muisti voidaan varata dynaamisesti:

int* pX = (int*)malloc(4);

malloc()-funktio vaatii argumenttina varattavien tavujen määrän. Jos et tiedä tarvittavaa tavumäärää, mutta tiedät tallennettavan tietotyypin, voit muuttaa lauseketta näin:

int* pX = (int*)malloc(sizeof(int));

Mitä seuraavaksi? Huomaa, että sijoitamme malloc()-funktion tuloksen osoittimeen. Tämä tarkoittaa, että malloc() palauttaa osoitteen!

Etuliite (int*) on eksplisiittinen tyyppimuunnos. Määrittelemme halutun tyypin itse. Esimerkiksi:

double x = 3.14;
int y = (int)x;   // `y` = 3
Main.c

Main.c

copy
1234567891011
#include <stdio.h> #include <stdlib.h> // new header file! int main() { int* pX = (int*)malloc(sizeof(int)); printf("Address of allocated memory: %p\n", pX); return 0; }

Huom

Muista sisällyttää otsikkotiedosto stdlib.h. Se sisältää malloc()-funktion prototyypin.

Tallentaaksemme tietoa osoitteeseen, jonka malloc()-funktio palauttaa, käytämme osoitteen purku -operaattoria.

Main.c

Main.c

copy
123456789101112
#include <stdio.h> #include <stdlib.h> int main() { int* pX = (int*)malloc(sizeof(int)); *pX = 100; printf(" Value %d at address %p\n", *pX, pX); return 0; }

Onko mahdollista vapauttaa muistia? – Kyllä, mutta vain malloc()- ja vastaavien funktioiden varaama muisti voidaan vapauttaa.

free()

Tätä funktiota käytetään osoittimien kanssa. Havainnollistetaan asiaa laajentamalla yllä olevaa esimerkkiä:

Main.c

Main.c

copy
1234567891011121314151617
#include <stdio.h> #include <stdlib.h> int main() { int* pX = (int*)malloc(sizeof(int)); *pX = 100; printf(" Value %d at address %p\n", *pX, pX); free(pX); printf("After `free()` value %d at address %p\n", *pX, pX); return 0; }

On mielenkiintoista, että vaikka osoitin "poistetaan", se säilyy toiminnallisena, mutta siihen liittyvän muistipaikan arvo muuttuu epäluotettavaksi.

Tämä aiheuttaa ongelman: varattu muistisolun sisältö on nyt epäluotettavaa tietoa. Tällaisen tilanteen estämiseksi käytetty osoitin tulisi asettaa arvoon NULL.

Main.c

Main.c

copy
1234567891011121314151617
#include <stdio.h> #include <stdlib.h> int main() { int* pX = (int*)malloc(sizeof(int)); *pX = 100; printf("Value %d at address %p\n", *pX, pX); free(pX); pX = NULL; return 0; }

Osoittimen asettaminen arvoon NULL vapauttamisen jälkeen on selkeä tapa osoittaa, ettei osoitin enää viittaa kelvolliseen muistipaikkaan.

Tarkista aina, onko osoitin NULL ennen sen käyttöä varmistaaksesi, ettet käytä virheellistä tai jo varattua muistia.

Oliko kaikki selvää?

Miten voimme parantaa sitä?

Kiitos palautteestasi!

Osio 6. Luku 4
some-alt