Ha olyan nyelven kódol, mint a C vagy a C ++, akkor alacsonyabb szintű interakcióba léphet a memóriájával. Néha ez sok problémát vet fel, amelyeket korábban nem kapott: szegfaults . Ezek a hibák meglehetősen bosszantóak, és sok bajt okozhatnak. Gyakran jelzik, hogy olyan memóriát használ, amelyet nem szabad használni.
Az egyik leggyakoribb probléma a már felszabadult memória elérése. Ez olyan memória, amelyet vagy kiadott free
, vagy memória, amelyet a program automatikusan felszabadított, például a veremből.
Mindezek megértése nagyon egyszerű, és mindenképpen jobb és intelligensebb programozásra készteti.
Hogyan oszlik meg a memória?

A memória több szegmensre oszlik. Ennek a bejegyzésnek a két legfontosabb a verem és a halom . A verem rendezett beillesztési hely, míg a kupac véletlenszerű - a memóriát mindenhol lefoglalja, ahol csak tudja.
A verem memóriának számos módja és művelete van a munkájához. Itt tárolják a processzor regisztrációinak egy részét. És hová kerülnek a programoddal kapcsolatos releváns információk - mely függvényeket hívják meg, milyen változókat hoztál létre, és még néhány további információt. Ezt a memóriát szintén a program kezeli, és nem a fejlesztő.
A halmot gyakran használják nagy memóriamennyiségek kiosztására, amelyek állítólag léteznek, amíg a fejlesztő akarja. Ez azt jelenti, hogy a fejlesztő feladata ellenőrizni a halom memóriájának használatát . Összetett programok készítésekor gyakran nagy memóriarészeket kell kiosztani, és itt használja a kupacot. Ezt dinamikus memóriának hívjuk .
Minden alkalommal a halomra helyezi a dolgokat, amikor malloc
valamire memóriát rendel. Bármely más hívás, amelyik hasonló int i;
, verem memória. Ennek ismerete nagyon fontos, hogy könnyen megtalálhassa a hibákat a programjában, és tovább javítsa a Segfault hibakeresését.
A verem megértése
Bár lehet, hogy nem tud róla, a program folyamatosan kiosztja a verem memóriáját a működéséhez. Minden helyi változó és minden hívott funkció oda megy. Ezzel sok mindent megtehet - ezek többnyire olyan dolgok, amelyekre nem akartál sort keríteni -, például a puffer túlcsordulása és a helytelen memória elérése.
Tehát hogyan működik valójában?
A verem egy LIFO (Last-In-First-Out) adatszerkezet. Megtekintheti tökéletesen illeszkedő könyvek dobozaként - az utoljára elhelyezett könyv az első, amelyet kivesz. Ennek a struktúrának a használatával a program könnyen kezelheti az összes műveletet és hatókört két egyszerű művelettel: push és pop .
Ez a kettő pontosan ellentétesen cselekszik egymással. Nyomja meg az értéket a verem tetejére. A pop a felső értéket veszi tőle.

Az aktuális memóriahelyek nyomon követéséhez van egy speciális processzorregiszter, Stack Pointer néven . Minden alkalommal, amikor el kell mentenie valamit - például egy változót vagy egy függvény visszatérési címét -, az felfelé tolja és mozgatja a verem mutatóját. Minden alkalommal, amikor kilép egy funkcióból, a verem mutatójától kezdve mindent a függvény elmentett visszatérési címéig ugrik elő. Ez egyszerű!
Teszteljük, megértettük-e a következő példát (próbáld meg egyedül megtalálni a hibát ☺️):

Ha futtatja, akkor a program egyszerűen szegfault. Miért történik ez? Minden a helyén látszik! Kb. ... a verem kivételével.
Amikor meghívjuk a függvényt createArray
, a verem:
- elmenti a visszatérési címet,
- létrehoz
arr
a verem memóriájában és visszaadja (egy tömb egyszerűen egy memóriahelyre mutató mutató az információival) - de mivel nem használtuk
malloc
, a verem memóriájába kerül.
Miután visszaküldtük a mutatót, mivel nincs kontrollunk a veremműveletek felett, a program eldobja az információkat a veremből, és szükség szerint felhasználja azokat. Amikor megpróbáljuk kitölteni a tömböt, miután visszatértünk a funkcióból, megrongáltuk a memóriát - ezzel a program szétbomlott.
A halom megértése
A verem ellenében a halom az, amelyet akkor használ, ha azt szeretné, hogy valami létezzen egy ideig a funkcióktól és a hatóköröktől függetlenül. Ennek a memóriának a használatához a C nyelv stdlib nagyon jó, mivel két félelmetes funkciót hoz: malloc
és free
.
A Malloc (memóriaallokáció) kéri a rendszert a kért memóriamennyiségért, és egy mutatót ad vissza a kiindulási címre. A Free azt mondja a rendszernek, hogy a kért memóriára már nincs szükség, és más feladatokhoz használható. Nagyon egyszerűnek tűnik - mindaddig, amíg elkerüli a hibákat.
A rendszer nem tudja felülírni azt, amit a fejlesztők kértek. Tehát rajtunk, embereken múlik, hogy a fenti két funkcióval kezeljük-e. Ez megnyitja az ajtót egy emberi hibának: a memória kiszivárog.
A memóriaszivárgás a felhasználó által kért memória, amelyet soha nem szabadítottak fel - amikor a program véget ért, vagy a helyére mutató mutatók elvesznek. Ezáltal a program sokkal több memóriát használ fel, mint amire kellett volna. Ennek elkerülése érdekében minden alkalommal, amikor már nincs szükségünk halomra allokált elemre, felszabadítjuk.

A fenti képen a rossz út soha nem szabadítja fel az általunk használt memóriát. Ez végül 20 * 4 bájtot pazarol (int-méret 64 bitesben) = 80 bájt. Lehet, hogy ez nem tűnik annyira, de képzelje el, hogy ezt nem óriási programban tenné meg. Végül gigabájtokat pazarolhatunk!
A halom memória kezelése elengedhetetlen a programok memóriájának hatékonyabbá tétele érdekében. De arra is ügyelnie kell, hogy miként használja. Csakúgy, mint a verem memóriájában, a memória felszabadulása után is annak elérése vagy használata segfaultot okozhat.
Bónusz: Struktúrák és a kupac
A struktúrák használatakor az egyik leggyakoribb hiba a struktúra felszabadítása. Ez rendben van, amíg nem osztottunk memóriát a struktúrán belüli mutatókra. Ha memóriát osztanak ki a struktúrán belüli mutatókra, akkor először meg kell szabadítanunk őket. Ezután felszabadíthatjuk a teljes struktúrát.

Hogyan oldom meg a memóriaszivárgás problémáimat
Legtöbbször, amikor C-ben programozok, struktúrákat használok. Ezért mindig két kötelező funkciót kell használnom a szerkezeteimmel : a konstruktort és a destruktort .
Ez a két funkció az egyetlen, ahol a mallocs-okat használom, és felszabadítom a struktúrát. Ez igazán egyszerűvé és könnyen megoldhatóvá teszi a memóriaszivárgásaimat.
(Ha többet szeretne tudni a kód könnyebb olvashatóságáról, ellenőrizze az absztrakcióról szóló bejegyzésemet).

Remek memóriakezelő eszköz - Valgrind
Nehéz kezelni a memóriát, és megbizonyosodni arról, hogy mindent helyesen kezelt. Remek eszköz a Valgrind ellenőrzésére, ha programja megfelelően viselkedik. Ez az eszköz ellenőrzi a programot, megmondva, hogy mennyi memóriát rendelt el, mennyit szabadított fel, ha helytelen memóriaterületre próbált írni ... Ennek használata nagyszerű módja annak ellenőrzésére, hogy minden rendben van-e, és ezt el kell használnia az elkerülése érdekében biztonsági kompromisszumok.

Ne felejtsd el követni!
A Mediumon való közzététel mellett a Twitteren is vagyok.
Ha bármilyen kérdése vagy javaslata van, ne habozzon kapcsolatba lépni velem.