Mi az a heap (c++)?
És a változó címét a stack-ban tárolja, amit szintén nem tudom hogy mi.
Ezek magyaráznák az alábbi kódok eredményeit, de nem teljesen értem hogy jönnek ki.
int* a = new int;
*a = 4;
cout << a << endl;
cout << *a << endl;
cout << &a << endl;





3 tárolási mód van. Mindegyiknek meg van a maga feladata.
Static:
Olyan tároló, amely adott változó 1x létezik és ha bárhonnan ráhivatkozol, eléred. Általában az OOP-ben használják.
Stack:
Magyarul verem. Olyan adatszerkezet, ahol amit elsőnek teszel be, azt tudod utoljára kivenni. Mint, ha gödröt ásnál és beletennéd mondjuk a könyveid egyesével. Nyilván a legfelsőt tudnád elsőnek kivenni, ha azt is egyesével teszed. Verembe tárolja a metórusok és függvények belső változóit (is). Ha "return"-t hívsz, onnantól az adott függvényen belül az összes ott definiált változó elvész, mert kiveszi a veremből. Tehát ez a memória rész felszabadul. Ha return-olsz értéket, akkor is felszabadul, csak ez esetben "kimásolja" és egy másik verembe helyezi, ahova visszatér a hívás.
Heap:
Ide a dinamikus objektumok, class-ok példányai és ide kerülnek vagy C/C++ esetén a pointerezett értékek. Ennek takarítása és karbantartása a programozó felelőssége, mert *memória szivárgást is eredményezhet.
Az, hogy hova helyeződik el az adat, lényegében arra a válasz: ahol van hely neki.
Persze a Java vagy például a C# már "GC"-t futtat, ami nyilván tartja mihez mi tartozik, így a "takarítást" is ő végzi el. Míg a programozó csak azt mondja: megszünteti a pointert/referenciát, de a memória felszabadítással nem kell foglalkoznia. C++ban ezt a programozó végzi.
*Memória szivárgás: Olyan memória foglalás, amihez már nincs rá mutató változó vagy objektum. Így felszabadítás sem lehetséges, mert "nem tudjuk, hol van". Tehát egy memoria szivárgásos függvényt sokszor hívunk, képes betelni a több GB memória. Ekkor a programot meg kell állítani, hogy felszabaduljon, addig a rendszer nem nyúl hozzá, mert ő szerinte még kellhez, mert a program foglalta le.





Minden programnak legalább három szegmense van.
Ezek a kód-, az adat- és a veremszegmens.
A kódszegmens alapból csak olvasható, ezt írni nem lehet (mondjuk a vírusoknak azért sikerül). A másik kettő viszont írható és olvasható.
A programokban vannak, legalábbis lehetnek előre definiált változók és konstansok. Ezek "kerülnek" a futásidő legelején az adatszegmensbe,
Ezen kívül, vannak olyan változók, amelyek esetlegesek, nem biztos, hogy létre lesznek hozva és a méretük sem tudható előre.
Ilyen pl. ha egy szövegszerkesztőt futtat valaki. Lehet, hogy ezer soros szövegfájlt tölt be a user, de lehet, hogy csak húsz sorosat, vagy éppen érdemi munka nélkül fogja magát és kilép.
Mondjuk, hogy a user betölt egy szöveget. Ekkor a változó (a szövegfájl puffere) futásidőben jön létre és a mérete is akkor lesz meghatározva, a szövegfájl méretétől függően.
Na, az ilyen a dinamikusan létrehozott változók kerülnek a HEAP-re.
A STACK akkor jut szerephez, HA (!) a program a futása során meghív egy függvényt. Ekkor a progi a STACK-en létrehozza a függvény konstansait, változóit, valamint a függvény paramétereit is a STACK-en helyezi el és a visszatérési címet is eltárolja a STACK-en, hogy tudja, hova kell visszatérnie a függvény lefuttatása után.
Ha a függvény már lefutott, akkor a STACK-en létrehozott változók, konstansok, visszatérési érték, cím és minden más ami a függvényhez tartozik, végérvényesen megsemmisül.
De ismétlem, ez csak akkor történik meg, HA (!) a függvény egyáltalán meg lesz hívva, mert ez azért nem olyan biztos.
Viszont ha a függvény a futásidő során tizenhatezerszer lesz meghívva, akkor ez a fent ismertetett folyamat is tizenhatezerszer fog megismétlődni.
Erre való a STACK.
Képzeld el, ha STACK nem lenne, akkor minden egyes függvénynek memót kéne foglalni, akkor is, ha nem is futna le éppen.
Ebből talán látszik a STACK haszna, létjogosultsága.





Első kettő nem tudom, miért lett lepontozva, megpróbáltak segítőkész, kimerítő választ adni a kérdezőnek.
Kis kiegészítés: A stack nem csak függvényhíváskor használatos, hanem bármilyen blokk lokális változói is oda kerülnek (ahogy a függvény blokk paraméterei és lokális változói). Pl. C-ben bárhol csinálok egy { ilyen blokkot és változót hozok létre benne; } az is a stack-be kerül, és blokk végén felszabadul.
- Heap / memory pool / dynamic memory: ez olyan memória terület, amit az op.rendszer oszt ki futás közben, igénytől függően. Például itt foglalódik le a malloc() által kért memória.
- Statikus adatok: ez leginkább a globális változók területe, amik életciklusa az egész futásidőre kiterjed. A futtatható fájlban meg van adva, mennyi, milyen méretű, milyen kezdőértékű adatokról van szó. A program betöltődésekor ezek lefoglalódnak és beállítódnak, mire az első utasítás végrehajtása elindul.
- Stack / verem: Speciális szervezésű memória-rész, ahogy fentebb írták, egy veremhez hasonlít, ahova felülre pakolhatsz adatokat, és fordított sorrendben tudod kivenni őket. A fő célja, hogy az egymást hívó, vagy egymásba ágyazott blokkok a saját lokális adataikat ill. a visszatérési címeiket itt tárolják. Például ha egy függvény meghív egy másikat, akkor a másik szépen berakja a verem tetejére a saját változóit, mikor végez, "kidobálja" onnan, és amikor visszatér a hívó függvényhez a végrehajtás, akkor megint az előző függvény ott hagyott adatai lesznek felül, ott folytathatja a munkát, ahol abbahagyta. (A függvényhívás is ide teszi és a return is innen veszi ki a címet, ahova vissza kell térnie, így tudja a sok függvény egymást hívni, és mind jó helyre fog visszatérni.)










int* a = new int; // dinamikus helyfoglalás egy int változónak, az oda mutató pointer neve: 'a' (a pointer egy spec. változó, tuképpen memóriacím)
*a = 4; // az 'a' által mutatott helyre 4 (int) beírása
cout << a << endl; // az 'a' pointer értékének kiírása
cout << *a << endl; // az 'a' által mutatott érték kiírása
cout << &a << endl; // az 'a' pointer memória címének kiírása.





off
Ennél az egyszerű proginál most nem érdekes, de azért szokd meg, hogy ha new-t használsz, akkor delete-et is használj, vagyis a lefoglalt memóriát szabadítsd fel.
delete a;





Kedves 4.
Azért lettünk lepontozva mert Magyarországon vagyunk... Széthúzás 4ever. :D De olyannyira lex@rom a pontozást. :) Boldog-boldogtalannak van pontozni a másikat.





"Ezek magyaráznák az alábbi kódok eredményeit"
Nem hiszem, rossz irányba keresgélsz, a két dolognak nincs sok köze egymáshoz. Inkább a pointerek/mutatók témakörét nézd át alaposabban.
További kérdések:
Minden jog fenntartva © 2025, www.gyakorikerdesek.hu
GYIK | Szabályzat | Jogi nyilatkozat | Adatvédelem | Cookie beállítások | WebMinute Kft. | Facebook | Kapcsolat: info(kukac)gyakorikerdesek.hu
Ha kifogással szeretne élni valamely tartalommal kapcsolatban, kérjük jelezze e-mailes elérhetőségünkön!