C Programmeerimine

malloc c keeles

malloc c keeles
Siia võite tulla kahel põhjusel: kas soovite sisu dünaamiliselt jaotada või soovite rohkem teada saada, kuidas malloc töötab. Mõlemal juhul olete õiges kohas! Dünaamiline jaotamine on protsess, mida juhtub palju, kuid üldjuhul me seda ise ei kasuta: valdav osa programmeerimiskeeltest haldab teie jaoks mälu, kuna see on raske töö ja kui te ei suuda seda korralikult teha, on selle mõju turvalisusele.

Kui aga teete C-, C ++- või koostekoodi või kui rakendate uue välismooduli oma lemmikprogrammeerimiskeeles, peate dünaamilise mälu jaotust ise haldama.

Mis on dünaamiline jaotamine? Miks mul on vaja malloci?

Noh, kõigis rakendustes, kui loote uue muutuja - seda nimetatakse sageli muutuja deklareerimiseks - selle salvestamiseks vajate mälu. Kuna teie arvuti on tänapäeval, võib see käitada korraga rohkem kui ühte rakendust ja seega peaks iga rakendus sellest oma operatsioonisüsteemile rääkima (siin Linux) et see vajab nii palju mälu. Sellise koodi kirjutamisel tehke järgmist

# kaasata
# kaasata
#define DISK_SPACE_ARRAY_LENGTH 7
void getFreeDiskSpace (int statsList [], size_t listLength)
tagasi;

int main ()
/ * Sisaldab viimase 7 päeva vaba kettaruumi. * /
int freeDiskSpace [DISK_SPACE_ARRAY_LENGTH] = 0;
getFreeDiskSpace (freeDiskSpace, DISK_SPACE_ARRAY_LENGTH);
tagastage EXIT_SUCCESS;

Massiiv freeDiskSpace vajab mälu, nii et mälu saamiseks peate Linuxilt kinnitust küsima. Kuid lähtekoodi lugedes on ilmne, et vajate massiivi 7 int, küsib kompilaator seda automaatselt Linuxilt ja eraldab selle virna. Põhimõtteliselt tähendab see, et see salvestusruum hävitatakse, kui tagastate funktsiooni, kus muutuja deklareeritakse. Sellepärast ei saa te seda teha:

# kaasata
# kaasata
#define DISK_SPACE_ARRAY_LENGTH 7
int * getFreeDiskSpace ()
int statsList [DISK_SPACE_ARRAY_LENGTH] = 0;
/ * MIKS me seda teeme?! statsList hävitatakse! * /
return statsList;

int main ()
/ * Sisaldab viimase 7 päeva vaba kettaruumi. * /
int * freeDiskSpace = NULL;
freeDiskSpace = getFreeDiskSpace ();
tagastage EXIT_SUCCESS;

Nüüd näete probleemi kergemini? Seejärel soovite liita kaks stringi. Pythonis ja JavaScriptis teete järgmist:

newStr = str1 + str2

Kuid nagu teate, C-s see nii ei toimi. Nii et näiteks URL-i loomiseks peate liitma kaks stringi, näiteks URL-i tee ja domeeninimi. C-s oleme strcat, eks, kuid see töötab ainult siis, kui teil on selle jaoks piisavalt ruumi sisaldav massiiv.

Teil on kiusatus teada saada stringi abil uue stringi pikkus ja teil oleks õigus. Aga siis, kuidas te paluksite Linuxil reserveerida see tundmatu mälumaht? Kompilaator ei saa teid aidata: täpne ruum, mille soovite eraldada, on teada ainult käituse ajal. Just seal vajate dünaamilist jaotust ja malloci.

Oma esimese C-funktsiooni kirjutamine malloci abil

Enne koodi kirjutamist väike selgitus: malloc võimaldab teil eraldada konkreetse baitide arvu oma rakenduse kasutamiseks. Selle kasutamine on tõesti lihtne: helistate mallocile vajaliku baitide arvuga ja see tagastab kursori teie uude piirkonda, mille Linux teile reserveeris.

Teil on ainult 3 kohustust:

  1. Kontrollige, kas malloc tagastab NULL. See juhtub siis, kui Linuxil pole piisavalt mälu.
  2. Kui muutujad on kasutamata, vabastage need. Vastasel juhul raiskate mälu ja see aeglustab teie rakendust.
  3. Ärge kunagi kasutage mälutsooni pärast muutuja vabastamist.

Kui järgite kõiki neid reegleid, läheb kõik hästi ja dünaamiline jaotamine lahendab teile palju probleeme. Kuna valite mälu vabastades, saate mallociga eraldatud muutuja ka turvaliselt tagastada. Lihtsalt, ärge unustage seda vabastada!

Kui mõtlete, kuidas muutujat vabastada, on see vaba funktsiooniga. Helistage sellele sama kursoriga, kui malloc teid tagastas, ja mälu on vaba.

Lubage mul näidata teile lühike näide:

# kaasata
# kaasata
# kaasata
/ *
* Sellele funktsioonile helistades ärge unustage kontrollida, kas tagastusväärtus on NULL
* Kui see pole NULL, peate pärast selle väärtust helistama tagastatud kursorile tasuta
* ei kasutata enam.
* /
char * getUrl (const char * const baseUrl, const char * const toolPath)
suurus_t lõplikUrlLen = 0;
char * finalUrl = NULL;
/ * Ohutuskontroll. * /
kui (baseUrl == NULL || toolPath == NULL)
return NULL;

finalUrlLen = strlen (baseUrl) + strlen (toolPath);
/ * Ärge unustage '\ 0', seega ka + 1. * /
finalUrl = malloc (sizeof (char) * (finalUrlLen + 1));
/ * Malloci reeglite järgimine ... * /
kui (finalUrl == NULL)
return NULL;

strcpy (finalUrl, baseUrl);
strcat (finalUrl, toolPath);
return finalUrl;

int main ()
char * googleImages = NULL;
googleImages = getUrl ("https: // www.google.com "," / imghp ");
kui (googleImages == NULL)
tagastage EXIT_FAILURE;

put ("Tööriista URL:");
paneb (googleImages);
/ * Seda pole enam vaja, vabastage see. * /
tasuta (googleImages);
googleImages = NULL;
tagastage EXIT_SUCCESS;

Nii et näete praktilist näidet dünaamiliste eraldiste kasutamiseks. Esiteks väldin selliseid lõkse nagu getUrli tagastusväärtuse andmine otse funktsiooni. Seejärel võtan aega ka kommenteerimiseks ja dokumenteerimiseks, et tagastusväärtus tuleks õigesti vabastada. Samuti kontrollin kõikjal NULL-väärtusi, et kõik ootamatu saaks rakenduse krahhi asemel ohutult kinni püüda.

Lõpuks hoolitsen selle eest, et muutuja vabastataks ja määraksin seejärel NULL. See väldib kiusatust kasutada - isegi ekslikult - nüüd vabanenud mälutsooni. Kuid nagu näete, on muutujat lihtne vabastada.

Võite märgata, et ma kasutasin mallofis suurust. See võimaldab teada saada, mitu baiti söe kasutab, ja selgitab koodis oleva kavatsuse, et see oleks loetavam. Char'i puhul on sizeof (char) alati võrdne 1-ga, kuid kui kasutate selle asemel massiivi int, töötab see täpselt samamoodi. Näiteks kui peate reserveerima 45 int, tehke lihtsalt järgmist

fileSizeList = malloc (sizeof (int) * 45);

Nii näete kiiresti, kui palju soovite eraldada, seetõttu soovitan alati selle kasutamist.

Kuidas töötab malloc kapoti all?

malloc ja free on tegelikult kõigi C-programmide funktsioonid, mis räägivad teie nimel Linuxiga. See muudab ka dünaamilise jaotamise lihtsamaks, sest alguses ei luba Linux teil eraldada igas suuruses muutujaid.

Linux pakub tegelikult rohkem mälu saamiseks kahte võimalust: sbrk ja mmap. Mõlemal on piirangud ja üks neist on: saate eraldada ainult suhteliselt suuri summasid, näiteks 4096 baiti või 8 192 baiti. Te ei saa taotleda 50 baiti, nagu mina näitel, kuid te ei saa taotleda ka 5894 baiti.

Sellel on seletus: Linux peab pidama tabelit, kus ta ütleb, milline rakendus on millise mälutsooni reserveerinud. Ja see tabel kasutab ka ruumi, nii et kui iga bait vajaks selles tabelis uut rida, oleks vaja suurt osa mälust. Sellepärast jagatakse mälu suurteks plokkideks, näiteks 4096 baiti, ja umbes nii, nagu ei saa toidupoest osta 2 ja pool apelsini, ei saa ka poolikuid plokke küsida.

Nii et malloc võtab need suured plokid ja annab teile väikese osa neist mäluplokidest alati, kui seda kutsute. Samuti, kui vabastasite vähe muutujaid, kuid mitte piisavalt, et õigustada terve ploki vabastamist, võib malloc-süsteem hoida plokke ja taaskasutada mälutsoone, kui helistate uuesti mallocile. Selle eeliseks on malloci kiirem muutmine, kuid malloci reserveeritud mälu ei saa kasutada üheski muus rakenduses, kuigi programm seda reaalsuses praegu ei kasuta.

Kuid malloc on tark: kui helistate mallocile, et eraldada 16 MiB või suur summa, küsib malloc Linuxilt tõenäoliselt mmapiga selle täismõõdulisi blokke. Nii väldite tasuta helistades suurema tõenäosusega ruumi raiskamist. Ärge muretsege, malloc teeb ringlussevõtu osas paremat tööd kui inimene meie prügiga!

Järeldus

Ma arvan, et nüüd saate paremini aru, kuidas see kõik töötab. Muidugi on dünaamiline jaotamine suur teema ja ma arvan, et me võime kirjutada sellel teemal terve raamatu, kuid see artikkel peaks teid mõistma nii üldiselt kui ka praktiliste nõuannete osas.

Kuidas muuta hiire ja puuteplaatide kerimise suund Windows 10-s ümber
Hiir ja PuuteplaatNeed muudavad arvutamise mitte ainult lihtsaks, vaid ka tõhusamaks ja vähem aeganõudvaks. Me ei kujuta ette elu ilma nende seadmetet...
Kuidas muuta hiirekursori ja kursori suurust, värvi ja skeemi Windows 10-s
Windows 10 hiirekursor ja kursor on operatsioonisüsteemi väga olulised aspektid. Seda võib öelda ka teiste opsüsteemide kohta, nii et tegelikult pole ...
Tasuta ja avatud lähtekoodiga mängumootorid Linuxi mängude arendamiseks
See artikkel hõlmab loetelu tasuta ja avatud lähtekoodiga mängumootoritest, mida saab kasutada 2D- ja 3D-mängude arendamiseks Linuxis. Selliseid mängu...