Halom vs. Verem a Delphi Developers számára

Hívja egyszer a "DoStackOverflow" funkciót a kódod és megkapod a EStackOverflow Delphi által felvetett hiba a "verem túlcsordulása" üzenettel.


funkció DoStackOverflow: egész szám;

kezdődik

 eredmény: = 1 + DoStackOverflow;

végén;

Mi ez a "verem", és miért van ott túlcsordulás a fenti kód használatával?

Tehát a DoStackOverflow funkció rekurzívan hívja magát - "kilépési stratégia nélkül" - csak forog, és soha nem lép ki.

Gyors javítás, ha megtenné, törölje a nyilvánvaló hibát, és ellenőrizze, hogy a funkció egy bizonyos pontban létezik-e (így a kódja folytathatja a futtatást attól a helytől, ahova hívta a függvényt).

Haladsz, és soha nem nézel vissza, nem törődsz a hibával / kivétellel, mivel ez már megoldódott.

Ugyanakkor a kérdés továbbra is fennáll: mi ez a verem és miért van túlcsordulás??

Memória a Delphi alkalmazásokban

Amikor elkezdi a programozást a Delphi-ben, előfordulhat, hogy olyan hibát tapasztal, mint a fentiek, megoldja és továbblép. Ez a memóriaelosztáshoz kapcsolódik. Legtöbbször nem fog törődni a memóriaelosztással, amíg te szabadítsa fel azt, amit létrehoz.

instagram viewer

Ahogy a Delphi-ben több tapasztalatot szerez, elkezdi létrehozni saját osztályait, közvetítheti őket, törődik a memóriakezeléssel és egyaránt.

Eljut a pontra, ahol a Súgóban olyasmit olvassa el "A helyi változók (az eljárásokon és a funkciókon belül deklaráltak) az alkalmazásban találhatók Kazal." és még Az osztályok referencia típusok, tehát nem másolják őket a hozzárendeléskor, referenciákkal adják át őket, és kiosztják őket halom.

Szóval, mi az a "verem", és mi a "halom"?

Stack vs. Halom

Az alkalmazás futtatása Windows rendszeren, a memóriában három olyan terület található, ahol az alkalmazás tárolja az adatokat: globális memória, halom és verem.

A globális változókat (értéküket / adataikat) a globális memória tárolja. A globális változók számára fenntartott memóriát az alkalmazás fenntartja a program indulásakor, és addig marad lefoglalva, amíg a program le nem fejeződik. A globális változók memóriáját "adatszegmensnek" nevezzük.

Mivel a globális memória csak egyszer van kiosztva és felszabadítva a program befejezésekor, ebben a cikkben nem törődünk vele.

A veremben és a halomban történik a dinamikus memóriaelosztás: amikor egy függvényt létrehoz egy változót, amikor létrehoz egy osztálypéldányt, amikor paramétereket küld egy függvénynek, és felhasználja / átadja annak eredményét érték.

Mi az a verem?

Ha egy változót deklarál egy funkción belül, akkor a változó megtartásához szükséges memóriát a verem fogja kiosztani. Egyszerűen írja a "var x: integer" kifejezést, használja az "x" értéket a funkciójában, és amikor a funkció kilép, akkor nem törődik a memória allokációjával és a felszabadítással. Amikor a változó hatókörén kívül esik (kód kilép a funkciótól), a verembe vett memória felszabadul.

A veremmemóriát a LIFO ("utoljára az elsőben ki") megközelítéssel dinamikusan osztják el.

Ban ben Delphi programok, a veremmemóriát a

  • Helyi rutin (módszer, eljárás, funkció) változók.
  • Rutin rutinok és visszatérési típusok.
  • Windows API funkció felhívja.
  • Rekordok (ezért nem kell kifejezetten létrehoznia egy rekordtípus példányát).

Nem kell kifejezetten felszabadítania a veremben lévő memóriát, mivel a memória automatikusan varázslatosan kiosztódik az Ön számára, amikor például egy függvény helyi változóját deklarálja. Amikor a funkció kilép (néha még a Delphi fordító optimalizálása miatt), a változó memóriája automatikusan varázslatosan felszabadul.

Verem memória mérete alapértelmezés szerint elég nagy a (bármilyen összetett) Delphi programhoz. A projekt Linker opciói "Maximális veremméret" és "Minimális veremméret" értékei megadják az alapértelmezett értékeket - 99,99% -ban nem kell módosítania ezt.

Gondolj egy halomra, mint egy halom memóriablokkra. Amikor kijelenti / használja egy helyi változót, a Delphi memóriakezelő felülről kiválasztja a blokkot, felhasználja azt, és amikor már nincs rá szüksége, akkor visszaadja a verembe.

Ha a veremből helyi változó memóriát használunk, akkor a helyi változók nem kerülnek inicializálásra, amikor deklaráljuk. Nyisson meg egy változót "var x: integer" néhány függvényben, és csak próbálja meg kiolvasni az értéket, amikor beírja a függvényt - x lesz valamilyen "furcsa" nulla értéke. Tehát mindig inicializálja (vagy állítsa be az értéket) a helyi változókhoz, mielőtt elolvassa azok értékét.

A LIFO miatt a verem (memória allokáció) műveletek gyorsak, mivel csak néhány műveletre (push, pop) van szükség a verem kezeléséhez.

Mi a halom?

Egy halom a memória olyan területe, amelyben a dinamikusan elosztott memória tárolódik. Amikor létrehoz egy osztálypéldányt, a memóriát a halomból osztják le.

A Delphi programokban a halom memóriát a / mikor használja

  • Osztálypéldány létrehozása.
  • Dinamikus tömbök létrehozása és átméretezése.
  • A memória kifejezett kiosztása a GetMem, FreeMem, New és Dispose () használatával.
  • ANSI / széles / Unicode karakterláncok, variációk, interfészek használatával (a Delphi automatikusan kezeli).

A halommemórianak nincs szép elrendezése, ahol lenne valamilyen sorrend a memóriablokkok kiosztására. A halom úgy néz ki, mint egy doboz golyó. A memóriakiosztás a halomból véletlenszerűen történik, innen egy blokk, mint onnan egy blokk. Így a halom műveletek egy kicsit lassabbak, mint a veremben végrehajtottak.

Amikor új memóriablokkot kér (azaz létrehoz egy osztálypéldányt), a Delphi memóriakezelő ezt fogja kezdeni az Ön számára: kapsz egy új memóriablokkot vagy egy használt és eldobott memóriablokkot.

A halom az összes virtuális memóriából (RAM és lemezterület).

A memória kézi elosztása

Most, hogy minden a memóriáról tisztán van, biztonságosan (a legtöbb esetben) figyelmen kívül hagyhatja a fentieket, és egyszerűen folytathatja a Delphi programok írását, ahogy tegnap tette.

Természetesen tisztában kell lennie azzal, hogy mikor és hogyan kell manuálisan elosztani a memóriát.

Az "EStackOverflow" (a cikk elejétől) felmerült, mivel minden DoStackOverflow híváskor a memória új szegmense került felhasználásra a veremből, és a verem korlátozott. Ilyen egyszerű az egész.

instagram story viewer