Ц Програмирање

маллоц на језику ц

маллоц на језику ц
Овде можете доћи из два разлога: или желите динамички алоцирати садржај или желите знати више о томе како маллоц ради. У оба случаја сте на правом месту! Динамичко додељивање је процес који се догађа много, али углавном га сами не користимо: велика већина програмских језика управља меморијом уместо вас, јер је то тежак посао, а ако то не учините правилно, постоје безбедносне импликације.

Међутим, ако радите Ц, Ц ++ или код за монтажу или ако имплементирате нови спољни модул на свом омиљеном програмском језику, морат ћете сами управљати динамичком додјелом меморије.

Шта је динамичка алокација? Зашто ми треба маллоц?

Па, у свим апликацијама, када креирате нову променљиву - често се назива декларисање променљиве - потребна вам је меморија да бисте је чували. Како је ваш рачунар у модерно доба, истовремено може да покреће више апликација, тако да свака апликација треба да каже вашем оперативном систему (овде Линук) да му је потребна та количина меморије. Када напишете ову врсту кода:

#инцлуде
#инцлуде
#дефине ДИСК_СПАЦЕ_АРРАИ_ЛЕНГТХ 7
воид гетФрееДискСпаце (инт статсЛист [], сизе_т листЛенгтх)
повратак;

инт маин ()
/ * Садржи слободан простор на диску у последњих 7 дана. * /
инт фрееДискСпаце [ДИСК_СПАЦЕ_АРРАИ_ЛЕНГТХ] = 0;
гетФрееДискСпаце (фрееДискСпаце, ДИСК_СПАЦЕ_АРРАИ_ЛЕНГТХ);
ретурн ЕКСИТ_СУЦЦЕСС;

Низу ФрееДискСпаце треба меморија, па ћете требати да питате Линук за одобрење да бисте добили меморију. Међутим, како је очигледно приликом читања изворног кода да ће вам требати низ од 7 инт, компајлер аутоматски тражи Линук за њега и додијелит ће га у стек. То у основи значи да се ово складиште уништава када вратите функцију у којој је променљива декларисана. Зато то не можете учинити:

#инцлуде
#инцлуде
#дефине ДИСК_СПАЦЕ_АРРАИ_ЛЕНГТХ 7
инт * гетФрееДискСпаце ()
инт статсЛист [ДИСК_СПАЦЕ_АРРАИ_ЛЕНГТХ] = 0;
/ * ЗАШТО ТО РАДИМО?! статсЛист ће бити УНИШТЕНО! * /
ретурн статсЛист;

инт маин ()
/ * Садржи слободан простор на диску у последњих 7 дана. * /
инт * фрееДискСпаце = НУЛЛ;
фрееДискСпаце = гетФрееДискСпаце ();
ретурн ЕКСИТ_СУЦЦЕСС;

Сада лакше видите проблем? Затим желите да спојите два низа. У Питхону и ЈаваСцрипт-у бисте урадили:

невСтр = стр1 + стр2

Али као што знате, у Ц-у то не функционише овако. Дакле, да бисте направили УРЛ, на пример, морате да спојите два низа, као што су путања УРЛ-а и име домена. У Ц-у смо стрцат, тачно, али ради само ако имате низ са довољно простора за то.

Бићете у искушењу да сазнате дужину новог низа користећи стрлен и били бисте у праву. Али како бисте онда тражили да Линук резервише ову непознату количину меморије? Преводник вам не може помоћи: тачан простор који желите да доделите познат је само током извођења. Управо ту вам треба динамичка алокација и маллоц.

Писање моје прве Ц функције помоћу маллоц-а

Пре писања кода, мало објашњење: маллоц вам омогућава да доделите одређени број бајтова за употребу ваше апликације. Заиста је једноставан за употребу: зовете маллоц са потребним бројем бајтова и враћа показивач на ваше ново подручје које је Линук резервисао за вас.

Имате само 3 одговорности:

  1. Проверите да ли маллоц враћа НУЛЛ. То се дешава када Линук нема довољно меморије за пружање.
  2. Ослободите променљиве једном неискоришћене. У супротном ћете изгубити меморију и то ће успорити вашу апликацију.
  3. Никада не користите меморијску зону након што сте ослободили променљиву.

Ако се придржавате свих ових правила, све ће проћи добро, а динамична алокација решиће вам многе проблеме. Будући да ви бирате када ослободите меморију, такође можете безбедно да вратите променљиву додељену маллоц-ом. Само, не заборавите да га ослободите!

Ако се питате како да ослободите променљиву, то је са бесплатном функцијом. Позовите га истим показивачем него што вам је вратио маллоц и меморија се ослобађа.

Показаћу вам пример цонцат:

#инцлуде
#инцлуде
#инцлуде
/ *
* Када позивате ову функцију, не заборавите да проверите да ли је повратна вредност НУЛЛ
* Ако није НУЛЛ, морате вратити фрее на враћеном показивачу једном када вредност
* се више не користи.
* /
цхар * гетУрл (цонст цхар * цонст басеУрл, цонст цхар * цонст тоолПатх)
сизе_т финалУрлЛен = 0;
цхар * финалУрл = НУЛЛ;
/ * Сигурносна провера. * /
иф (басеУрл == НУЛЛ || тоолПатх == НУЛЛ)
ретурн НУЛЛ;

финалУрлЛен = стрлен (басеУрл) + стрлен (тоолПатх);
/ * Не заборавите на '\ 0', дакле + 1. * /
финалУрл = маллоц (сизеоф (цхар) * (финалУрлЛен + 1));
/ * Следење маллоц правила ... * /
иф (финалУрл == НУЛЛ)
ретурн НУЛЛ;

стрцпи (финалУрл, басеУрл);
стрцат (финалУрл, тоолПатх);
ретурн финалУрл;

инт маин ()
цхар * гооглеИмагес = НУЛЛ;
гооглеИмагес = гетУрл ("хттпс: // ввв.гоогле.цом "," / имгхп ");
иф (гооглеИмагес == НУЛЛ)
ретурн ЕКСИТ_ФАИЛУРЕ;

пут ("УРЛ алата:");
ставља (гооглеИмагес);
/ * Више није потребно, ослободите га. * /
бесплатно (гооглеИмагес);
гооглеИмагес = НУЛЛ;
ретурн ЕКСИТ_СУЦЦЕСС;

Дакле, видите практични пример коришћења динамичких алокација. Прво, избегавам замке попут давања повратне вредности гетУрл директно у функцију путова. Затим, узимам времена и за коментарисање и документовање чињенице да би повратна вредност требала бити правилно ослобођена. Такође свуда проверавам да ли постоје НУЛЛ вредности, тако да се све неочекивано може сигурно ухватити уместо да сруши апликацију.

На крају, водим додатну бригу о ослобађању променљиве и затим постављању показивача на НУЛЛ. То избегава да дођете у искушење да користите - чак и грешком - сада ослобођену меморијску зону. Али као што видите, променљиву је лако ослободити.

Можда ћете приметити да сам користио сизеоф у маллоц-у. Омогућава да зна колико бајтова користи цхар и појашњава намеру у коду, тако да је читљивији. За цхар, сизеоф (цхар) је увек једнак 1, али ако уместо тога користите низ инт, то функционише на потпуно исти начин. На пример, ако требате резервисати 45 инт, само урадите:

филеСизеЛист = маллоц (сизеоф (инт) * 45);

На овај начин брзо видите колико желите да доделите, зато увек препоручујем његову употребу.

Како делује маллоц испод хаубе?

маллоц и фрее су, заправо, функције укључене у све Ц програме који ће у ваше име разговарати са Линуком. Такође ће олакшати динамичку алокацију јер вам Линук на почетку не дозвољава да доделите променљиве свих величина.

Линук заправо нуди два начина да добије више меморије: сбрк и ммап. Оба имају ограничења, а једно од њих је: можете доделити само релативно велике количине, као што су 4.096 бајтова или 8.192 бајта. Не можете тражити 50 бајтова као што сам ја урадио у примеру, али такође не можете захтевати 5.894 бајтова.

Ово има објашњење: Линук треба да држи табелу у којој говори која је апликација резервисала коју меморијску зону. А и ова табела користи простор, па ако би сваком бајту био потребан нови ред у овој табели, био би потребан велики удео меморије. Због тога се меморија дели на велике блокове од, на пример, 4.096 бајтова, и слично као што не можете купити 2 поморанџе и по у намирници, не можете тражити пола блокова.

Дакле, маллоц ће узети ове велике блокове и даће вам мали део тих меморијских блокова кад год га позовете. Такође, ако сте ослободили неколико променљивих, али недовољно да оправдате ослобађање целог блока, систем маллоц може задржати блокове и рециклирати меморијске зоне када поново позовете маллоц. То има предност што бржи маллоц, међутим меморија коју резервише маллоц не може се користити у било којој другој апликацији, док је програм тренутно не користи у стварности.

Али маллоц је паметан: ако позовете маллоц да додели 16 МиБ или већу количину, маллоц ће вероватно тражити од Линука пуне блокове намењене само овој великој променљивој помоћу ммап. На овај начин, када позовете бесплатан, вероватније ћете избећи то губљење простора. Не брините, маллоц обавља много бољи посао у рециклажи него што људи раде са нашим смећем!

Закључак

Мислим да сада боље разумеш како све то функционише. Наравно, динамичка алокација је велика тема и мислим да можемо да напишемо целу књигу на ту тему, али овај чланак би требало да вам олакша концепт, уопште и практичне савете за програмирање.

Средњи тастер миша не ради у оперативном систему Виндовс 10
Тхе средње дугме миша помаже вам да се крећете кроз дугачке веб странице и екране са пуно података. Ако се то заустави, на крају ћете користити тастат...
Како да промените леви и десни тастер миша на рачунару са Виндовс 10
Сасвим је нормално да су сви уређаји рачунарског миша ергономски дизајнирани за дешњаке. Али постоје доступни уређаји за миш који су посебно дизајнира...
Емулирајте кликове мишем лебдењем помоћу миша без клика у оперативном систему Виндовс 10
Коришћење миша или тастатуре у погрешном положају прекомерне употребе може резултирати многим здравственим проблемима, укључујући напрезање, синдром к...