Dinamikus memóriafoglalás C++ nyelven

Dinamikus Memoriafoglalas C Nyelven



Normális esetben a C++ programozási nyelvű forráskódok használata közben a fordító manuálisan lefoglalja a memóriát az adatok tárolására szolgáló változóhoz. Azt mondják, hogy ez a statikus memória lefoglalása. Ez egy rögzített memória, amelyet deklarálás után nem lehet megváltoztatni. Az ilyen típusú memóriakiosztáshoz az operációs rendszer a verem segítségével tárolja az adatokat. Statikus kiosztás esetén a memória lefoglalása a forráskód végrehajtásának megkezdése előtt történik.

Míg a dinamikus memóriafoglalásnál a memória lefoglalása a végrehajtás megkezdése közben történik. Ezt a memóriát a programozó manuálisan foglalja le futási időben, más néven futási memóriakiosztás a C++ nyelven. A dinamikus memória mérete a programban tetszőleges pozícióban változtatható, mert a deklaráláskor nem említünk rögzíthető méretet. Csak közvetlenül a változóhoz adjuk meg az értéket.

A memóriafoglalás különbsége a normál változókhoz képest

A normál változókban a fordító által lefoglalt memória automatikusan lefoglalódik és felszabadításra kerül. Amikor a memóriát a programozó dinamikusan lefoglalja, akkor el kell távolítania vagy fel kell szabadítania a memóriát, ha az nem használ a forráskód további végrehajtásában. Ez a helyzet „memóriaszivárgást” okoz, amikor a program leáll, miközben a memória nincs felszabadítva.







Operátorok a dinamikus kiosztáshoz

A C++-ban két operátor segít a memóriafoglalásban és -felszabadításban: a „new” és a „delete”, amelyeket a memória jobb lefoglalására és felszabadítására használnak.



Új operátor

Memóriafoglalási igényt jelöl. Az új operátor inicializálja a memóriát, és visszaadja a lefoglalt memória címét a mutatóváltozónak, ha van elég szabad memória.



Mutató objektum = új adat - típus ;

Operátor törlése

Az új operátorhoz hasonlóan a törlés operátort is használjuk a lefoglalt memória eltávolítására. C++ nyelven a programozó ezt az operátort használhatja felosztásra.





# Mutató_változó törlése;

1. példa

Ebben a példában két mutatót mutatunk be: az egyik egy egész típusú mutató, a másik pedig egy lebegőmutató. A mutatók inicializálása csillagjel használatával történik.

# Int * pointInt;
# Float *pointfloat;

E két nyomtató használatával dinamikusan lefoglaljuk a memóriát.



A mutatók szerepe a dinamikus allokációban:
A tárhely memóriáját blokkok formájában fejlesztik. Amikor végrehajtunk egy programot vagy bármilyen műveletet, a memória az adott célra van lefoglalva. Ennek a memóriának van egy speciális címe, amely a programhoz van társítva, amely azonosítja, hogy melyik folyamat vagy program engedélyezett az adott memóriához. Bármely memórianyílás elérhető azon a címen keresztül, amelyhez tartozik. Tehát ezt a címet a mutatók tárolják. Röviden, mutatókra van szükségünk a memória eléréséhez, és ugyanígy ahhoz, hogy a memória egy részét lefoglaljuk bármilyen feladathoz. A mutatók a címek tárolásához szükségesek.

Mivel az „új” kulcsszót a memória dinamikus lefoglalására használják a kézi kiosztás során, a memóriát a fordító foglalja le. Nem kell memóriát lefoglalnunk futási időben. De mivel a dinamikus kiosztás véletlenszerű, azonosítanunk kell a mutatókat, és a kötési folyamathoz ezt az új operátort kell használni.

# Pointint = új int;

Hasonlóképpen, a lebegő mutató is ugyanígy van kötve. A kötési folyamat után tetszőleges értéket rendelünk ahhoz a memóriához, amelyet le kívánunk foglalni bármely művelethez. A mutató deklarálásával egy adott értéket rendelünk a memóriához.

# *pointInt = 50;

A pontlebegések lebegőértéke is deklarálva van. Az értékek megjelenítése a hozzárendelés után.

Amint már megbeszéltük, az „új” operátort a memória lefoglalására, míg a „delete” operátort a memória felszabadítására használják. Tehát miután befejezte a kódban szereplő feladatot vagy műveletet, eltávolítjuk a feladathoz lefoglalt memóriát.

Jobb, ha felszabadítja a memória ezt a részét, hogy bármely más folyamat hasznosítsa ezt. Ezt a kiosztást alkalmazzuk mindkét mutatóra.

Pont törlése úszó ;

Miután elmentette a kódot a szövegszerkesztőben, az Ubuntu terminál lehetővé teszi a forráskód futtatását a fájlban egy g++ fordítón keresztül.

$ g++ -o mem mem.c
$ ./mem

A végrehajtás után látni fogja a memóriához rendelt értékeket.

2. példa

Ebben a példában a felhasználói interakció szerepel. Fogunk egy számváltozót, amely a felhasználó értékeit tartalmazza. Ez a program az eredményt a hallgatók GPA-jában tárolja. Az összes eredmény mentésre kerül futási időben.

Amikor a felhasználó megadja a tanulók számát, az egyes számokhoz memória kerül lefoglalásra. Itt egy lebegő típusú mutató inicializálódik, amelyet az eredmények memóriakiosztásához használunk.

A mutatót lebegő módban vesszük, mivel a GPA decimális jelöléssel történik. A GPA-hoz egy pointer típusú tömböt veszünk, mivel ez számos hallgató számára eredményezhet.

Ptr = új úszó [ az egyiken ]

Ez az „új” kulcsszót tartalmazó mutatótömb a végrehajtást a memóriához köti. A GPA-t minden hallgatóra be kell írni. Mivel nem ismerjük a felhasználó által felvenni kívánt hallgatók számát, egy for ciklust használtunk a GPA megadásához a megadott számig. A ciklus minden megismétlésekor a felhasználónak meg kell adnia a tanulót azonosító eredményt. Az eredmény mentése után ismét egy hurkot használunk a hallgatók összes GPA-jának megjelenítésére. Végül a mutató típusú tömb törlődik, mivel a dinamikus tárolás célja megvalósult.

Töröl [ ] ptr ;

Most a fent említett kódot fogjuk végrehajtani. A felhasználónak először meg kell adnia a tanulók számát. Ezután minden diák GPA-ja kerül megadásra.

3. példa

Ez a példa a new és delete operátorokat használja az osztály objektumához. Ez az osztály egy egész típusú privát változót tartalmaz, amely az életkort tárolja. Az osztály nyilvános részében létrejön a konstruktor, amely az életkort 10-es számra inicializálja. Itt egy másik függvényt használunk, amely megjeleníti a konstruktorban inicializált életkort.

Most áttérünk a dinamikus elosztás fő programjára. Az osztály objektuma dinamikusan jön létre.

Diák * ptr = új diák ( ) ;

Az objektum kialakításakor a konstruktor automatikusan megvalósul. Az életkor meghatározásához függvényhívás történik. Ez a ptr.

Ptr - > getAge ( ) ;

És a végén az emlék felszabadul.

Következtetés

A dinamikus memóriafoglalást futási idejű végrehajtáskor a programozó foglalja le a fordító által azonosított rögzített tárhely helyett. Ez az elosztás véletlenszerű, és felhasználása után megszüntethető. Míg a legtöbb esetben az eltávolítás előtt a végrehajtási folyamat leáll, és ez a dinamikus kiosztás okozza a memóriaszivárgást. Ezt a jelenséget különböző megközelítésekben valósítottuk meg az Ubuntu Linux rendszerben C++ programozási nyelv használatával.