Једном сазовите функцију "ДоСтацкОверфлов" свој код и добићеш ЕСтацкОверфлов грешка коју је Делпхи покренуо поруком "стацк оверфлов".
функција ДоСтацкОверфлов: цели број;
започети
резултат: = 1 + ДоСтацкОверфлов;
крај;
Шта је ово "стацк" и зашто се тамо прелива користећи горњи код?
Дакле, ДоСтацкОверфлов функција се рекурзивно позива - без „излазне стратегије“ - само се наставља вртећи и никада не престаје.
Брзо исправљање, то бисте требали учинити је да очистите очигледну грешку коју имате и осигурате да функција постоји у неком тренутку (тако да ваш код може наставити извршавати одакле сте функцију позвали).
Наставите даље и никад се не осврћете уназад, не марећи за грешку / изузетак као што је то сада решено.
Ипак, остаје питање: шта је овај стајк и зашто постоји преливање?
Меморија у вашим Делпхи апликацијама
Када почнете програмирати у Делпхију, можда ћете осјетити буг попут оног горе, ријешили бисте га и крените даље. Овај се односи на расподелу меморије. Већину времена се не бисте бринули о подели меморије све док то нисте ослободите оно што креирате.
Како стекнете више искуства у Делпхију, започињете креирати сопствене часове, инстанцирати их, бринути се за управљање меморијом и слично.
Доћи ћете до тачке где ћете у помоћи прочитати нешто попут "Локалне варијабле (декларисане у процедурама и функцијама) налазе се у апликацији гомила." и такође Класе су референтни типови, па се при задатку не копирају, прослеђују се референцама и распоређују се на гомила.
Дакле, шта је "стацк" и шта је "хеап"?
Стацк вс. Гомила
Покретање апликације у оперативном систему Виндовс, у меморији постоје три области у којима апликација чува податке: глобална меморија, хеап и стацк.
Глобалне променљиве (њихове вредности / подаци) се чувају у глобалној меморији. Меморија за глобалне променљиве резервисана је од ваше апликације када се програм покрене и остаје додељена док програм не престане. Меморија за глобалне променљиве назива се „сегмент података“.
Будући да се глобална меморија само једном додељује и ослобађа при прекиду програма, то нас у овом чланку не занима.
Стацк анд хеап су места где се одвија динамичка подела меморије: када креирате променљиву функцију, када креирате инстанцу класе када пошаљете параметре функцији и користите / проследите њен резултат вредност.
Шта је Стацк?
Када декларишете променљиву унутар функције, меморија потребна за држање променљиве додељује се из скупа. Једноставно напишете "вар к: интегер", користите "к" у својој функцији, а када функција изађе, не бринете о додељивању меморије нити ослобађању. Када варијабла изађе из обима (код напушта функцију), меморија која је узета у стог се ослобађа.
Меморија снопа распоређује се динамички користећи ЛИФО ("ласт ин фирст оут") приступ.
Ин Делпхи програми, меморија стацка користи
- Локалне рутинске (метода, поступак, функција) променљиве.
- Рутински параметри и типови повратка.
- Виндовс АПИ функција позиви.
- Записи (зато не морате експлицитно да креирате инстанцу типа записа).
Не морате изричито ослободити меморију на снопу, јер се меморија аутоматски додељује вама када, на пример, декларирате локалну променљиву функцију. Када функција изадје (понекад и раније због оптимизације Делпхи компајлера) меморија за променљиву ће се аутоматски магично ослободити.
Величина меморијске меморије је, подразумевано, довољно велик за ваше (толико сложене) Делпхи програме. Вредности „Максимална величина хрпе“ и „Минимална величина хрпе“ на Линкер опцијама за ваш пројекат одређују подразумеване вредности - у 99,99% ово не би требало да мењате.
Замислите хрпу као гомилу меморијских блокова. Када изјавите / употребите локалну променљиву, Делпхи менаџер меморије ће изабрати блок одозго, употребити га, а када више није потребан, вратит ће се назад у стог.
Употребљавајући локалну меморију променљивих која се користи из скупа, локалне променљиве се не иницијализирају када су деклариране. Прогласите променљиву "вар к: интегер" у некој функцији и покушајте само прочитати вредност када уђете у функцију - к ће имати неку "чудну" нулту вредност. Стога, увијек иницијализирајте (или поставите вриједност) на своје локалне варијабле прије него што прочитате њихову вриједност.
Захваљујући ЛИФО-у, операције слагања (распоређивања меморије) су брзе јер је за управљање снопом потребно само неколико операција (пусх, поп).
Шта је хеап?
Хеап је регија меморије у коју се похрањује динамички распоређена меморија. Када креирате инстанцу класе, меморија се додељује из гомиле.
У Делпхи програмима хеап меморија користи / вхен
- Креирање инстанције класе.
- Израда и промјена величине динамичких низова.
- Изричито додељивање меморије помоћу ГетМем, ФрееМем, Нев и Диспосе ().
- Кориштење АНСИ / широк / Уницоде жице, варијанте, интерфејси (аутоматски управља Делпхи).
Хеап меморија нема леп изглед, тамо где би био ред да се додељују блокови меморије. Хеап изгледа као лименка мермера. Додјела меморије из хрпе је насумична, блок одавде него блок оданде. Стога су операције гомиле нешто спорије од оних на хрпи.
Када тражите нови меморијски блок (тј. Створите инстанцу класе), Делпхи менаџер меморије ће ово решити за вас: добићете нови меморијски блок или коришћени и одбачени.
Копа се састоји од целе виртуалне меморије (РАМ-а и простора на диску).
Ручно распоређивање меморије
Сад кад је све о меморији јасно, можете сигурно (у већини случајева) занемарити горе наведено и једноставно наставити писање Делпхи програма као што сте то радили јуче.
Наравно, требали бисте бити свјесни када и како ручно распоредити / ослободити меморију.
Подигнут је "ЕСтацкОверфлов" (с почетка чланка), јер се сваким позивом на ДоСтацкОверфлов користи нови сегмент меморије из снопа, а стацк има ограничења. Тако једноставна.