- Alacsony profilú, madzagmentes klaviatúrák jöttek a Razer színeiben
- ASUS ROG csúcslap érkezett, ezúttal a "lopakodó" fajtából
- Átvette a DRAM-piac trónját az SK Hynix a Samsungtól
- Pénztárcabarát, ugyanakkor trendi mikrotorony jött a Jonsbótól
- A Linux támogatását vágja meg leginkább az Intel leépítése
- Milyen asztali (teljes vagy fél-) gépet vegyek?
- Calibre, az elektronikus könyvtár
- VR topik (Oculus Rift, stb.)
- NVIDIA GeForce RTX 5070 / 5070 Ti (GB205 / 203)
- AMD Ryzen 9 / 7 / 5 9***(X) "Zen 5" (AM5)
- Egérpad topik
- Először égett le egy újságnál a GeForce RTX 5090
- Milyen belső merevlemezt vegyek?
- Kezdő fotósok digitális fényképei
- Nikon DSLR topik
Új hozzászólás Aktív témák
-
mgoogyi
senior tag
válasz
Teasüti #4155 üzenetére
Amit lehet a stacken jobb tartani(gyorsabb, nem kell delete), a nagy méretű adatot meg heap-en(van neki hely gazdagon).
A new+delete párra meg vannak osztályok, amikbe becsomagolva megkapod az eltakarítást.
std::vector a dinamikus tömbhöz, std::unique_ptr, std::auto_ptr egyéb mutatóhoz.
Ezek az osztályok a delete-et úgy oldják meg, hogy a destruktorukban meghívódik az általuk tárolt pointerre a delete.
És ezeket a pointer "wrapper"-eket pedig stack-en tartod valahol és amikor elhagyod a scope-ot, szépen lefut a destruktor és magától felszabadul a memória.
Ez azért nagyon fontos, mert minden programozó hibázik és nem igazán függ a hibázás gyakorisága attól, hogy mióta űzöd a mesterséget. Ezzel védjük magunkat a memory leak-től.A vector persze elsődlegesen nem pointer wrapper, arra találták ki, hogy nagyon kényelmesen legyen egy bármikor átméretezhető tömböd. A belsejében egy dinamikus tömb van.
-
jattila48
aktív tag
válasz
Teasüti #4153 üzenetére
"Tehát ami nekem átjött ebből a beszélgetésből, hogy ha new operátorral hozok létre tömböt (foglalok le dinamikus memóriát), akkor az egy ún. heap-re kerül,..."
Ez igaz.
"...míg ha new nélkül, akkor a stack-be."
Ez nem feltétlenül igaz, mert a globális adatterületen is deklarálhatsz tömböt.
Egyéb gyakorlati jelentősége pedig az, amit eddig leírtam. Röviden összefoglalva:
- A tömb név nem változó, nem adhatsz neki értéket, és nem képezheted a címét.
-A pointer változó, ami memória címet tartalmaz (pl. a heapen lefoglalt memória címét, de lehet más pl. "hagyományosan" deklarált tömb címe is). A pointer értéke megváltoztatható, és a címe is képezhető.
-Tömböt csak konstans méretűt deklarálhatsz (kivéve C99), míg new-val változó méretű memóriát foglalhatsz.
-Tömböt nem szabad felszabadítani, new-val létrehozott memóriát pedig fel kell szabadítani.
Kb. ennyi ami gyakorlatban különbség a két fogalom között, és amiről minden programozónak tudnia kell.
Még egy "apróság": C++ -ban tömb név, mint konstans pointer lehet template argumentum (mivel fordítási időben kiértékelhető), pointer viszont nem (mivel csak futási időben értékelhető ki). -
jattila48
aktív tag
válasz
Teasüti #4135 üzenetére
"De hisz a tömb is egy pointer.
"
Nem, nem az! C-ben valóban hasonlóan kezelheted a tömböt és a pointert, de ettől még a tömb nem pointer. Sok félreértés és hiba forrása ez, ugyanakkor nagyon kényelmes is tud lenni. A pointer egy változó, ami történetesen memória címet tartalmaz. Mint minden változónak, neki is van címe, és megváltoztathatod az értékét (balérték). Ezzel szemben a tömb egy konstans memória cím (ahol a tönb kezdődik). Ezt a konstanst a fordító/linker/betöltő számolja ki, amit te nem változtathatsz meg, és a címét sem képezheted (hiszen nem is létezik a memóriában).
int tomb[10];
tomb=new int[10]; //Hiba! tombnek nem lehet erteket adni, hiszen az konstans
int **ppi=&tomb; //Hiba! tombnek nem kepezheto a cime, mert az nem valtozo
int *pi=new int[10]; //OK
int **ppi=π //OK valtozonak kepezheto a cime
pi=new int[10]; //OK valtozo erteke megvaltoztathatoAmikor tömb elemre hivatkozol (kiindexeled), a fordító ehhez a konstans címhez adja hozzá az indexet, és erről a címről veszi elő a tömb elemet (intelnél egyetlen utasítás pl. : mov eax, DWORD PTR[ebx+0x1000]; indirekt indexelt címzési mód, ahol 0x1000-nél kezdődik a tömb, ebx-ben pedig az elérni kívánt tömbelem indexe található). Tehát itt a kódba a fordító beleírja a tömb konstans kezdőcímét.
Ha new-val foglalsz helyet, akkor a lefoglalt memória kezdőcímét egy változó kapja értékül, ez a változó a pointer. Ha ezen a memória területen tömb szintaxissal hivatkozol egy elemre, akkor a fordítónak (intel esetén) ehhez legalább két utasításra lesz szüksége. Az elsővel regiszterbe tölti a változó (pointer) címéről a változó értékét (ez maga a new-val foglalt memória kezdőcíme lesz). Ha pl. a pointered címe eax-ben van, akkor mov eax,DWORD PTR[eax] utasítás ezt megoldja. Majd az elem elérése mov eax,DWORD PTR[eax+esi] utasítással történik, ahol az esi tartalmazza azi indexet. Látható, hogy ez jóval lassabb művelet, mint az "igazi" tömb kiindexelése. -
mgoogyi
senior tag
válasz
Teasüti #4135 üzenetére
Igen, így van, a tömböt is pointerként kezeled. Gyakorlatilag a 0. elemére mutató pointer van a változóban értékként.
A kérdésedre a válasz igen, mindig más memóriaterületen kapsz egy új összefüggő memóriaterületet az új tömbödnek. A pointert írasd ki és látod, hogy mindig más értéket kap. Ez a logikai címe a kezdeti memóriacellának (a programod csak a memória egy számára logikailag elkülönített részét látja).
A régi tömb ugyanúgy meglesz az előző ciklusodból, csak a címe már nem lesz meg és anélkül nehéz felszabadítani.
Csináld ciklus belsejében simán, amit írtál. Ha jó sok kört fut a ciklusod, megzabálja a géped memóriáját.
Azért figyelj arra, hogy ne zabálja meg az összeset, kevés elemű int tömböt foglalj le 1000-szer ciklusban, kísérletnek elég. -
mgoogyi
senior tag
válasz
Teasüti #4132 üzenetére
A new meg nem new között az a különbség, hogy a new-val a heap-en foglalsz memóriát, new nélkül meg a stack-en. (itt nem erre a nem szabványos dologra gondolok:
int p [I]= {};
)
Ez utóbbi elég limitált tud lenni, ha majd egyszer írsz rekurzív(önmagát hívó) függvényt, belefuthatsz.
Ezt hívják stackoverflow-nak. Olvass utána, hogy mi az a heap és mi az a stack.
Egyébként paraméterezett méretű tömböt new nélkül nehéz lértehozni.A new (new []) esetében egy pointer-t kapsz vissza és a te feladatod ezt eltakarítani delete-tel ( delete []).
Azért, hogy ezt ne felejtsd el, javasolt olyan osztályokat használni, amik megteszik ezt helyetted.
A vector meghívja helyetted a new[]-t és a delete[]-t, menet közben át is méretezi a benne lévő array-t.
Kényelmessé és biztonságossá teszi a tömbkezelést.
A unique_ptr pedig általánosságban jó arra, hogy egy objektum felszabadításával ne kelljen foglalkozni.Ha ezeket nem használod és elfelejteted a delete-et, akkor keresheted, hogy miért növekszik a progid memóriahasználata (memóriaszivárgás).
-
válasz
Teasüti #4132 üzenetére
"Még sose alkalmaztam new-t. Mi szükségem volna rá, ha meg tudom oldani lokális változókkal?"
Ha meg tudod oldani, akkor semmi
Akkor van rá szükséged, ha nem tudod megoldani lokális változókkal (pl mert azt a p[] tömböt visszatérési értékként akarod használni a függvényedben).
Új hozzászólás Aktív témák
Hirdetés
● ha kódot szúrsz be, használd a PROGRAMKÓD formázási funkciót!
- Spórolós topik
- Milyen asztali (teljes vagy fél-) gépet vegyek?
- XPEnology
- Milyen légkondit a lakásba?
- E-roller topik
- Elektromos autók - motorok
- Samsung Galaxy A34 - plus size modell
- Samsung Galaxy S21 Ultra - vákuumcsomagolás
- Calibre, az elektronikus könyvtár
- Elemlámpa, zseblámpa
- További aktív témák...
- Dell 16 Inspiron 5625 FHD+ IPS Ryzen5 5625U 4.3Ghz 16GB 512GB SSD Radeon RX Vega7 Win11 Garancia
- Új Dell 14 Inspiron 5415 FHD IPS Ryzen5 5500U 4.0Ghz 8GB 256GB SSD Radeon RX Vega7 Win11 Garancia
- Dell 14 Latitude 5440 FHD IPS i5-1245U vPro 4.4Ghz 10mag 16GB 256GB Intel Iris XE Win11 Pro Garancia
- HP 14 Elitebook 640 G9 FHD IPS i5-1235U 4.4Ghz 10mag 16GB 256GB Intel Iris XE Win11 Pro Garancia
- HP 14 Pavilion FHD IPS i5-1135G7 4.2Ghz 16GB RAM 512GB SSD Intel Iris XE Graphics Win11 Garancia
- Bomba ár! HP EliteBook 735 G6 - Ryzen PRO 5 I 8GB I 256GB SSD I 13,3" FHD I Cam I W10 I Gari!
- Apple Air Pad 5.generácio / 32GB / Wi-fi / 12Hó garancia
- Bomba ár! Lenovo IdeaPad 320S-13IKB - i5-8G I 8GB I 128SSD I 13,3" FHD I HDMI I Cam I W11 I Gari!
- BESZÁMÍTÁS! MSI B450M R5 5500 16GB DDR4 512GB SSD RTX 2060 Super 8GB Rampage SHIVA ADATA XPG 600W
- 134 - Lenovo Legion Pro 7 (16IRX8H) - Intel Core i9-13900HX, RTX 4090 - 3 év garancia
Állásajánlatok
Cég: FOTC
Város: Budapest