Safu. Ugawaji wa kumbukumbu C (kazi ya malloc) Jinsi malloc inavyofanya kazi

  • 29.06.2020

Ugawaji wa kumbukumbu ya nguvu kwa kutumia kazi ya maktaba ya malloc ina hatua zifuatazo.

1. Kuingizwa kwa faili ya kichwa malloc .h ndani ya programu kwa kutumia maagizo ya # pamoja .

2. Azimio la pointer ya aina inayohitajika, kwa mfano int * p;

3. Kuita kazi ya malloc kubainisha kiwango kinachohitajika cha kumbukumbu katika ka kama kigezo. Kwa kuwa kazi hiyo inarudisha matokeo ya kazi yake kwa njia ya kiboreshaji kwa aina batili, ubadilishaji wa aina hufanywa (aina ya matokeo hubadilishwa kuwa aina iliyoainishwa katika tamko). Thamani inayosababishwa imepewa kiboreshaji kilichotangazwa. Mfano:

p \u003d (int *) malloc (idadi ya vitu vya safu * saizi (int));

Badala yake int inaweza kubadilishwa na aina yoyote inayotolewa au ya programu.

4. Kuangalia ukweli wa mgao wa kumbukumbu. Ikiwa mgao wa kumbukumbu kwa kiwango kinachohitajika haiwezekani, kazi ya malloc inarudi null pointer NULL kama matokeo yake, sawa na thamani ya uwongo. Ikiwa mgao wa kumbukumbu umekamilika, tunaendelea kutekeleza programu; ikiwa sio hivyo, tunaiacha na utambuzi unaofaa juu ya kumbukumbu haitoshi. Mfano:

ikiwa (! p) ujumbe, toka; mwendelezo mwingine;

5. Kufungua kumbukumbu baada ya kumaliza kufanya kazi nayo. Ili kufanya hivyo, piga kazi ya f gee na utumie pointer kama hoja:

bure (p);

Thamani ya pointer iliyopatikana baada ya hatua ya 3 lazima ihifadhiwe hadi hatua ya 5. Vinginevyo, kumbukumbu zote zilizotengwa kwenye anwani hii zitapotea wakati programu imeondolewa, ambayo, mwishowe, inaweza kusababisha kumbukumbu ya kutosha na utendakazi wa mfumo wa uendeshaji. ...

Sababu ya kawaida ya kufungia kompyuta wakati wa kufanya kazi na kumbukumbu iliyotengwa kwa nguvu ni kutofautisha kati ya maagizo mabaya na maagizo ya bure (maagizo yote lazima yatumie pointer sawa) au kumbukumbu ya bure ya kutosha.

Kama mfano, fikiria pembejeo / pato la safu-nguvu ya pande moja ya urefu wa kiholela, iliyoainishwa kutoka kwa kibodi.

int i, n, * massiv; // tamko la pointer

cout<\u003e n; // ingiza saizi ya safu

massiv \u003d (int *) malloc (n * sizeof (int)); // ugawaji wa dynam.mem

ikiwa (! massiv) // angalia ukweli wa ugawaji wa kumbukumbu

{cout<

cout<

kupata ();

kurudi 0;)

cout<

kwa (i \u003d 0; i \u003e massiv [i]; // safu ya kuingiza

cout<

kwa (i \u003d 0; i

bure (massiv); // kumbukumbu ya bure

Katika programu hii, pointer hutumiwa tu kwa kutenga kumbukumbu ya lundo. Zaidi katika mpango huo, ufikiaji wa vitu vya safu hufanywa kupitia jina la safu, linalofanana na jina la pointer.

Unaweza pia kutumia kazi ya calloc () kutenga kumbukumbu kwa nguvu. Tofauti na malloc, kazi ya calloc, pamoja na kutenga eneo la kumbukumbu kwa safu ya vitu, pia huanzisha vitu vya safu na maadili ya sifuri.

Kulingana na toleo la C ++ lililotumiwa, kazi za farmalloc (), farcalloc (), farcoreleft (), na farfree () zinaweza kutumika kufanya kazi na vipande vikubwa vya chungu.

Kila wakati pointer ilipoanzishwa, anwani ya anuwai ilitumika. Hii ilitokana na ukweli kwamba mkusanyaji wa C ++ hutenga kiotomatiki kumbukumbu ya kuhifadhi anuwai na kutumia pointer, unaweza kufanya kazi na eneo hili lililotengwa bila matokeo. Walakini, kuna kazi za malloc () na za bure () ambazo hukuruhusu kutenga na kumbukumbu ya bure kama inahitajika. Kazi hizi ziko kwenye maktaba na zina syntax ifuatayo:

utupu * malloc (size_t); // kazi ya ugawaji wa kumbukumbu
bure bure (utupu * memblock); // kazi ya kumbukumbu ya bure

Hapa size_t ni saizi ya eneo la kumbukumbu lililotengwa kwa ka; batili * ni aina ya kiashiria cha jumla, i.e. haijafungwa kwa aina yoyote. Wacha tuangalie utendaji wa kazi hizi kwa kutumia mfano wa ugawaji wa kumbukumbu kwa vitu 10 vya aina mbili.

Orodha 4.3. Programu ya safu ya nguvu.

#jumlisha
#jumlisha
int kuu ()
{
mara mbili * ptd;
ptd \u003d (mara mbili *) malloc (10 * sizeof (mara mbili));
ikiwa (ptd! \u003d NULL)
{
kwa (int i \u003d 0; i ptd [i] \u003d i;
) kingine printf ("Imeshindwa kutenga kumbukumbu.");
bure (ptd);
kurudi 0;
}

Wakati wa kuita kazi ya malloc (), eneo linalohitajika la kumbukumbu linahesabiwa kuhifadhi vitu 10 vya aina mbili. Ili kufanya hivyo, tumia kazi ya sizeof (), ambayo inarudisha idadi ya ka zinazohitajika kuhifadhi kitu kimoja mara mbili. Halafu thamani yake huzidishwa na 10 na matokeo yake ni ujazo wa vitu 10 vya aina mbili. Katika hali ambapo, kwa sababu fulani, idadi maalum ya kumbukumbu haiwezi kutengwa, kazi ya malloc () inarudi NULL. Mara kwa mara hii hufafanuliwa katika maktaba kadhaa, pamoja na. Ikiwa kazi ya malloc () ilirudisha pointer kwenye eneo la kumbukumbu lililotengwa, i.e. si sawa na NULL, kisha kitanzi kinatekelezwa, ambapo maadili ya kila kitu yameandikwa. Wakati mpango unatoka, kazi ya bure () inaitwa, ambayo huweka kumbukumbu iliyotengwa hapo awali. Rasmi, mpango ulioandikwa katika C ++, ukikamilika, huachilia moja kwa moja kumbukumbu zote zilizotengwa hapo awali na kazi ya bure (), katika kesi hii, inaweza kuachwa. Walakini, wakati wa kuandika programu ngumu zaidi, mara nyingi lazima utenge na kusambaza kumbukumbu mara nyingi. Katika kesi hii, kazi ya bure () ina jukumu muhimu, kwani kumbukumbu iliyoachiliwa haiwezi kutumiwa tena, ambayo itasababisha upotezaji wa lazima wa rasilimali za kompyuta.

Matumizi ya viashiria yalirithiwa kutoka kwa lugha ya C. Ili kurahisisha mchakato wa kubadilisha vigezo katika C ++, dhana kama rejeleo huletwa. Kiungo ni jina (au jina la kati) ambalo programu zinaweza kutumia kutaja tofauti. Kutangaza kiunga, programu hutumia & ishara mbele ya jina lake. Upekee wa kutumia viungo ni hitaji la kuzizindua mara moja wakati zinatangazwa, kwa mfano:

int var;
int & var2 \u003d var;

Hapa kiunga kinachoitwa var2 kinatangazwa, ambacho kimeanzishwa kwa var variable. Hii inamaanisha kuwa tofauti ya var ina majina yake mwenyewe var2, ambayo mabadiliko yoyote katika maadili ya tofauti ya var yanawezekana. Faida ya kutumia marejeleo juu ya viashiria ni kwamba lazima zianzishwe, kwa hivyo programu kila wakati ina hakika kuwa tofauti ya var2 inafanya kazi na eneo la kumbukumbu lililotengwa, na sio na moja holela, ambayo inawezekana wakati wa kutumia viashiria. Tofauti na vidokezo, kiunga huanzishwa mara moja tu, kinapotangazwa. Uanzishaji upya utasababisha kosa la wakati wa kukusanya. Hii inahakikisha kuaminika kwa utumiaji wa viungo, lakini inapunguza kubadilika kwa matumizi yao. Kawaida, marejeleo hutumiwa kama hoja za kazi kurekebisha vigeuzwa vilivyopitishwa ndani ya kazi. Mfano ufuatao unaonyesha utumiaji wa kazi kama hii:

Orodha 4.4. Mfano wa kutumia viungo.

ubadilishaji batili (int & a, int & b)
{
muda \u003d a;
a \u003d b;
b \u003d muda;
}
int kuu ()
{
int agr1 \u003d 10, arg2 \u003d 5;
wabadilishane (arg1, arg2);
kurudi 0;
}

Katika mfano huu, ubadilishaji () kazi inachukua hoja mbili, ambazo ni marejeleo ya vigeuzi viwili. Kutumia majina ya kumbukumbu a na b, unatumia vigeuzi vya arg1 na arg2 vilivyoainishwa katika kazi kuu main () na kupita kama vigezo kwa ubadilishaji () kazi. Faida ya ubadilishaji () kazi (ambayo hutumia marejeleo badala ya viashiria kwa vigeuzi) ni kwamba inahakikisha kuwa kazi hiyo inachukua aina zinazofaa za kutofautisha kama hoja, na sio habari nyingine yoyote, na kwamba marejeleo yameanzishwa kwa usahihi kabla ya kuyatumia. Hii inafuatiliwa na mkusanyaji wakati wa kubadilisha maandishi ya programu kuwa nambari ya kitu na ujumbe wa kosa hutengenezwa ikiwa utumiaji wa viungo sio sahihi. Tofauti na viashiria vyenye viungo, huwezi kufanya shughuli zifuatazo:

Huwezi kupata anwani ya kiunga ukitumia mwendeshaji wa anwani ya C ++;
huwezi kuwapa pointer kwa kiungo;
huwezi kulinganisha maadili ya kumbukumbu ukitumia waendeshaji wa kulinganisha wa C ++;
huwezi kufanya shughuli za hesabu kwenye kiunga, kwa mfano, ongeza pesa;

  • kuelezea pointer (aina * pointer;);
  • tambua saizi ya safu;
  • tenga kipande cha kumbukumbu kuhifadhi safu na upe anwani ya kipande hiki cha kumbukumbu kwa kiboreshaji.

Ili kutenga kumbukumbu katika C ++, unaweza kutumia mwendeshaji mpya au kazi za C - calloc, malloc, realloc. Kazi zote ziko kwenye maktaba ya stdlib.h.

5.2.1 kazi ya malloc

Malloc hutenga chunk inayojumuisha ya saizi za saizi na kurudisha pointer kwa baiti ya kwanza ya chunk hiyo. Simu ya kazi inaonekana kama:

utupu * malloc (size_t size);

ambapo saizi ni nambari kamili isiyosainiwa 1 size_t ni aina ya msingi isiyo kamili iliyosainiwa ya lugha ya C / C ++, ambayo huchaguliwa kwa njia ambayo saizi kubwa ya safu ya kinadharia ya aina yoyote inaweza kuandikwa ndani yake. Katika mfumo wa uendeshaji wa 32-bit, size_t ni nambari isiyosainiwa 32-bit (thamani ya juu ni 2 32 - 1), katika mfumo wa uendeshaji wa 64-bit, ni nambari isiyosajiliwa ya 64-bit (kiwango cha juu ni 2 64 - 1). , ambayo huamua saizi ya eneo la kumbukumbu lililotengwa kwa ka. Ikiwa uhifadhi wa kumbukumbu umefanikiwa, basi kazi inarudisha ubadilishaji wa aina ya batili, ambayo inaweza kubadilishwa kuwa aina yoyote ya kiashiria kinachohitajika. Ikiwa haiwezekani kutenga kumbukumbu, basi kazi itarudisha pointer null NULL.

Kwa mfano,

mara mbili * h; // Eleza pointer ili kuongezeka mara mbili. int k; sin \u003e\u003e k; // Ingiza nambari kamili k. // Tenga eneo la kumbukumbu la kuhifadhi vitu vya aina mbili. // Anwani ya sehemu hii imehifadhiwa kwa kutofautisha h. h \u003d (mara mbili *) malloc (k * sizeof (mara mbili)); // h - anwani ya mwanzo wa sehemu ya kumbukumbu, // h + 1, h + 2, h + 3, nk - anwani za vitu vifuatavyo vya aina mbili

5.2.2 Kazi ya calloc

Kazi ya calloc ni kwa kutenga na kuweka kumbukumbu ya kumbukumbu.

batili * calloc (size_t num, size_t size);

Kutumia kazi, kipande cha kumbukumbu kitatengwa ambayo vitu vya hesabu za saizi kila moja itahifadhiwa. Vipengele vyote vya eneo lililochaguliwa vimewekwa tena hadi sifuri. Kazi inarudi pointer kwa eneo lililotengwa au NULL ikiwa haiwezekani kutenga kumbukumbu.

Kwa mfano,

kuelea * h; // Eleza pointer ili kuelea. int k; sin \u003e\u003e k; // Ingiza nambari kamili k. // Tenga kipande cha kumbukumbu kuhifadhi vitu vya kuelea k. // Anwani ya sehemu hii imehifadhiwa kwa kutofautisha h. h \u003d (kuelea *) calloc (k, sizeof (kuelea)); // h - anwani ya mwanzo wa sehemu ya kumbukumbu, // h + 1, h + 2, h + 3, nk - anwani za vitu vifuatavyo vya kuelea.

5.2.3 Kazi ya realloc

Kazi ya realloc inapunguza ukubwa wa kumbukumbu iliyotengwa hapo awali. Kazi inaitwa kama hii:

batili * realloc (batili * p, saizi_t saizi);

ambapo p ni kiboreshaji cha eneo la kumbukumbu ili kugeuzwa ukubwa. Ikiwa, kama matokeo ya kazi, anwani ya eneo la kumbukumbu inabadilika, basi anwani mpya itarejeshwa kama matokeo. Ikiwa thamani halisi ya parameter ya kwanza ni NULL, basi kazi ya realloc inafanya kazi kwa njia sawa na kazi ya malloc, ambayo ni, inagawanya mkusanyiko wa kumbukumbu ya ka saizi.

5.2.4 Kazi ya bure

Kazi ya bure hutumiwa kutoa kumbukumbu iliyotengwa. Wanamshughulikia hivi:

bure bure (batili * p);

ambapo p ni pointer kwa eneo la kumbukumbu lililotengwa hapo awali na malloc, calloc, au realloc.

5.2.5 Waendeshaji mpya na ufute

Lugha ya C ++ ina waendeshaji mpya kwa ugawaji na kufuta kwa kufungua kipande cha kumbukumbu.

Ili kutenga kumbukumbu ya kuhifadhi vitu vya aina moja, mwendeshaji mpya ana fomu [

Programu yako lazima itoe kumbukumbu ya kutosha kuhifadhi data inayotumiwa. Baadhi ya maeneo haya ya kumbukumbu yametengwa kiatomati. Kwa mfano, tunaweza kutangaza

mahali pa char \u003d "Bay Bay ya Nguruwe";

na kumbukumbu ya kutosha itatengwa kukumbuka mstari huu.

Au tunaweza kuwa maalum zaidi na kuomba idadi maalum ya kumbukumbu:

sahani za int;

Maelezo haya hutenga sehemu 100 za kumbukumbu, kila moja kwa kuhifadhi nambari kamili.

Lugha C haishii hapo. Inakuwezesha kutenga kumbukumbu ya ziada wakati programu inaendelea. Tuseme, kwa mfano, unaandika programu ya maingiliano na haujui mapema ni kiasi gani cha data utakachoingia. Unaweza kutenga idadi ya kumbukumbu unayohitaji (kama unavyofikiria), halafu, ikiwa ni lazima, uhitaji zaidi. Katika mtini. 15.5 ni mfano wa kutumia kazi malloc ()kufanya hivyo tu. Pia, angalia jinsi programu kama hiyo hutumia viashiria.

/ * ongeza kumbukumbu ikiwa inahitajika * /

#jumlisha

#fafanua STOP "" / * ishara ya kuacha kuingiza * /

#fafanua ZUIA 100 / * ka kumbukumbu * /

#fafanua LIM 40 / * urefu wa kikomo cha laini ya kuingiza * /

#fafanua MAX 50 / * idadi kubwa ya mistari ya kuingiza * /

#fafanua DRAMA 20000 / * kucheleweshwa kwa muda mrefu * /

duka la char; / * chanzo cha kumbukumbu * /

char symph; / * mpokeaji wa laini za kuingiza * /

char * mwisho; / * inaonyesha mwisho wa kumbukumbu * /

char * inaanza; / * inaonyesha mwanzo wa mistari * /

int index \u003d 0; / * idadi ya mistari ya kuingiza * /

hesabu; / * kaunta * /

char * malloc (); / * mgawaji kumbukumbu * /

kuanza \u003d kuhifadhi;

mwisho \u003d kuanza + ZUIA - 1;

unaweka ("Taja orchestra za symphony.");

unaweka ("Ingiza moja kwa wakati: bonyeza kitufe cha [ingiza] mwanzoni");

unaweka ("mistari kukamilisha orodha yako. Ok, niko tayari.");

wakati (strcmp (fgets (symph, LIM, stdin), STOP)! \u003d 0 && index< MAX)

(ikiwa (strlen (symph)\u003e mwisho - kuanza)

(/ * vitendo ikiwa kutakuwa na kumbukumbu ya kutosha kukariri data ya kuingiza * /

unaweka ("Subiri kidogo. Nitajaribu kupata kumbukumbu zaidi.");

mwisho \u003d kuanza + ZUIA - 1;

kwa (hesabu \u003d 0; hesabu< DRAMA; count++);

unaweka ("Pata zingine!"); )

strcpy (kuanza, symph);

huanza \u003d kuanza + strlen (symph) + 1;

ikiwa (++ index< MAX)

printf ("Hii ni% d. Endelea ikiwa unapenda.n", faharisi); )

unaweka ("Ok, hii ndio nimepata:");

kwa (hesabu \u003d 0; hesabu< index; count ++)

unaweka (huanza);

MFANO. 15.5. Programu inayoongeza kumbukumbu juu ya mahitaji.

Hapa kuna mfano wa jinsi programu inavyofanya kazi:

Taja orchestra za orchestra kadhaa za symphony.

Waingize moja kwa moja; bonyeza kitufe cha [Enter] mwanzoni

mistari kukamilisha orodha yetu. O.k. niko tayari.

Symphony ya San Francisco.

Hii ni 1. Endelea ukipenda.

Symphony ya Chicago

Hii ni 2. Endelea ukipenda.

Philharmonic ya Berlin

Hii ni 3. Endelea ukipenda.

Chumba cha Moscow

Hii ni 4. Endelea ukipenda. Symphony ya London

Hii ni 5. Endelea ukipenda. Vienna Philharmonic

Subiri kwa sekunde. Nitajaribu kupata kumbukumbu ya ziada.

Kupatikana!

Hii ni 6. Endelea ukipenda.

Simoni ya Pittsburgh

Hii ni 7. Endelea ukipenda.

Sawa, hii ndio nimepata:

Symphony ya San Francisco

Symphony ya Chicago

Philharmonic ya Berlin

Chumba cha Moscow

Symphony ya London

Vienna Philharmonic

Simoni ya Pittsburgh

Kwanza, wacha tuone kazi inafanya nini malloc ()... Inachukua hoja isiyo kamili ya saini ambayo inawakilisha idadi ya kaiti za kumbukumbu zinazohitajika. Kwa hivyo, malloc (ZUIA) inahitaji baiti 100. Kazi inarudi pointer kwa aina char hadi mwanzo wa block mpya ya kumbukumbu. Tulitumia maelezo

char * malloc ();

kumuonya mkusanyaji kwamba malloc () inarudi pointer kuandika char... Kwa hivyo, tuliweka thamani ya kielekezi hiki kwa kipengee cha safu huanza na mwendeshaji

huanza \u003d malloc (BLOCK);

Ok, wacha sasa tuchunguze mradi wa programu hiyo, ambayo ni kukumbuka mistari yote ya asili mfululizo katika safu kubwa. duka... Tunataka kutumia huanza kutaja mwanzo wa mstari wa kwanza, huanza [l] - mstari wa pili, n.k Katika hatua ya kati, programu hiyo inaingia kwenye safu kwa safu symph... Tulitumia fgets () badala yake anapata ()kupunguza kamba ya kuingiza kwa urefu wa safu symph.

MFANO. 15.6. Mistari ya mfululizo ya symph iliyoandikwa kwa safu ya duka.

Kabla ya kunakili symph katika duka, lazima tuangalie ikiwa nafasi iliyobaki inatosha. Kiashiria mwisho inahusu mwisho wa kumbukumbu, na thamani ya sasa huanza inahusu mwanzo wa kumbukumbu isiyotumiwa. Kwa njia hii tunaweza kulinganisha tofauti kati ya viashiria hivi viwili na urefu symph na angalia ikiwa kuna kumbukumbu ya kutosha iliyobaki.

Ikiwa hakuna nafasi ya kutosha, tunapiga simu malloc ()kuandaa kumbukumbu ya ziada. Tunaweka huanza mwanzoni mwa kizuizi kipya cha kumbukumbu, a mwisho - mwishoni mwa kizuizi kipya. Kumbuka kuwa hatuna jina la kumbukumbu hii mpya. Kwa mfano, sio ugani duka... Tunayo tu majina ya viashiria vya kurejelea eneo mpya la kumbukumbu.

Wakati programu inaendesha, kila laini mpya inarejelewa na kipengee cha safu ya pointer huanza... Mistari mingine iko ndani duka, wengine - katika eneo moja au zaidi ya kumbukumbu.

Lakini maadamu tuna viashiria, tunaweza kufanya kazi na kamba, kama sehemu ya kuchapisha ya programu inatuonyesha.

Hivyo kutumika masaa ()... Lakini tuseme unataka kufanya kazi na kumbukumbu kama int, lakini sio char... Unaweza kutumia hapa pia masaa ()... Hivi ndivyo inavyofanyika:

char * malloc (); / * bado inaelezewa kama kiashiria cha char * /

int * mpya;

newmem \u003d (int *) malloc (l00); / * tumia operesheni ya kutupa * /

Tena ka 100 zinahitajika. Operesheni ya kutupa inabadilisha thamani iliyorudishwa na pointer kwa aina char, kwenye kiashiria cha aina int... Kama, kama ilivyo katika mfumo wetu, int inachukua kaiti mbili za kumbukumbu, hii inamaanisha kuwa newmem + 1 itaongeza pointer kwa ka mbili, ambayo ni, tusogeza kwa nambari ifuatayo. Hii inamaanisha pia kwamba ka 100 zinaweza kutumiwa kuhifadhi nambari 50.

Uwezekano mwingine wa ugawaji wa kumbukumbu hutolewa kwa kutumia kazi sallosi ():

char * calloc ();

muda mrefu * mpya;

newmem \u003d (ndefu *) calloc (100, sizeof (mrefu));

Kama malloc () kazi sallosi () inarudi pointer kwa char... Unahitaji kutumia opereta wa kutupwa ikiwa unataka kukumbuka aina tofauti. Kazi hii mpya ina hoja mbili, na zote mbili lazima ziwe nambari kamili. Hoja ya kwanza ina idadi ya maeneo ya kumbukumbu inahitajika. Hoja ya pili ni saizi ya kila seli kwenye ka. Kwa upande wetu ndefu

bure bure (batili * pointer);

ilitumika kutoa kumbukumbu iliyoonyeshwa na hoja ya pointer. Kwanza, kumbukumbu imetengwa kwa matumizi, baada ya kumaliza kazi na kumbukumbu, lazima irudishwe, na kazi ya bure inashughulika na kurudi.

_kubwa

Kazi ya _msize inarudisha saizi ya eneo la kumbukumbu lililotengwa kutoka kwa lundo:

saizi_t _msize (batili *);

hoja ni pointer kwa block ya kumbukumbu. Kazi ya _msize inarudisha saizi ya kumbukumbu katika ka. size_t haijatumiwa kamili.

malloc

Kazi ya malloc hutenga eneo la kumbukumbu kutoka kwa lundo (yaani eneo la kumbukumbu ya bure):

utupu * malloc (size_t);

hoja inabainisha idadi ya ka za kutenga kutoka kwa kumbukumbu. Kazi ya malloc inarudi kiboreshaji batili kwa eneo la kumbukumbu lililotengwa, inaweza kutupwa kwa aina inayotakiwa. Ikiwa kuna kumbukumbu ndogo ya bure ya ugawaji kuliko inavyotakiwa kwa size_t, basi kazi ya malloc itarudi NULL.

Mfano wa kufanya kazi na kazi ya malloc:

/ * Mwandishi: @author Subbotin B.P..h\u003e # pamoja na #jumlisha int kuu (batili) (inaweka ("Kumbukumbu"); int * pointer; inaweka ("kupata kumbukumbu"); pointer \u003d (int *) malloc (2 * sizeof (int)); int memorySize \u003d _msize (pointer); printf ("memory size \u003d% dn", memorySize); ikiwa (pointer \u003d\u003d NULL) (inaweka ("Matatizo"); kurudi EXIT_FAILURE;) bure (pointer); inaweka ("to free memory"); kurudi EXIT_SUCCESS;)

nafasi imetengwa hapa kwa safu ya vitu viwili vya int. Ikiwa mgao wa kumbukumbu ulifanikiwa, basi tunaachilia eneo hili la kumbukumbu kwa kutumia kazi ya bure.

Tunapata:

calloc

Kazi ya calloc hutenga eneo la kumbukumbu na kutenga safu iliyoanzishwa na sifuri ndani yake:

batili * calloc (size_t, size_t);

hoja ya kwanza ni idadi ya vitu, na ya pili ni saizi ya ka za kipengee kimoja. Bidhaa ya maadili ya hoja itatoa saizi ya eneo la kumbukumbu lililoombwa kwa mgawanyo. Kazi ya calloc inarudi kiboreshaji batili kwa eneo la kumbukumbu lililotengwa, inaweza kutupwa kwa aina inayotakiwa. Ikiwa kumbukumbu ya bure ya ugawaji iko chini ya inavyotakiwa, basi kazi ya calloc itarudi NULL.

Mfano wa kufanya kazi na kazi ya calloc:

/ * Mwandishi: @author Subbotin B.P..h\u003e # pamoja na #jumlisha int kuu (batili) (inaweka ("Kumbukumbu"); int * pointer; inaweka ("kupata kumbukumbu"); pointer \u003d (int *) calloc (2, sizeof (int)); int memorySize \u003d _msize (pointer); printf ("memory size \u003d% dn", memorySize); ikiwa (pointer \u003d\u003d NULL) (inaweka ("Matatizo"); kurudi EXIT_FAILURE;) bure (pointer); inaweka ("to free memory"); kurudi EXIT_SUCCESS;)

mfano hutenga kumbukumbu kwa safu ya ndani iliyo na vitu viwili. Vipengele hivi vimeanzishwa sifuri. Ikiwa mgao wa kumbukumbu ulifanikiwa, basi tunaachilia eneo hili la kumbukumbu kwa kutumia kazi ya bure.

Tunapata:

realloc

Kazi ya realloc inarekebisha eneo la kumbukumbu lililotengwa hapo awali:

batili * realloc (batili *, saizi_t);

hoja ya kwanza ni kiashiria kwa eneo la kumbukumbu ili kugeuzwa ukubwa, hoja ya pili inataja saizi mpya ya eneo la kumbukumbu. Ikiwa saizi hii ni sifuri, na hoja ya kwanza inaelekeza kwenye eneo la kumbukumbu linalopatikana, basi realloc itarudi NULL, na kizuizi cha kumbukumbu cha asili kilichoelekezwa na hoja ya kwanza kitaachiliwa. Ikiwa kumbukumbu ya bure ya ugawaji iko chini ya inavyotakiwa, basi kazi ya realloc itarudi NULL, na kizuizi cha kumbukumbu cha asili kilichoelekezwa na hoja ya kwanza kitabaki bila kubadilika. Kazi ya realloc inarudi kiboreshaji batili kwa eneo la kumbukumbu lililotengwa, inaweza kutupwa kwa aina inayotakiwa.