
C++ Alokacia a dealokacia pamati
Caute ucim sa C++ sorry za zaciatocnicke otazky ale rad by som si par veci ujasnil.
V C++ si programator moze zvolit kde alokuje pamat, ci na stacku alebo na halde. takze prva otazka:
1. kedy zvolit stack a kedy heap?
2. Dalsia vec chcem si ujasnit aky je rozdiel medzi tymito 3omi instanciaciami objektov?
auto objekt1 = Trieda();
objekt1.Metoda();
auto objekt2 = new Trieda();
objekt2->Metoda();
auto objekt3 = &Trieda();
objekt3->Metoda();
Prvy vytvara objekt na stacku. Druhy na halde a treti tiez na halde? Takze druhy a treti zapis je eqvivalentny?
3. kedy uvolnovat pamat? Ako zabranit tomu aby nastali memory leaky. Odkedy sa ucim C++ tak som zatial na ziadny problem nenarazil a to vobec nevolam delete. Takze aj v C++ sa uvolnuje pamat automaticky? Kedysi som programoval v Delphi a tam sa kazdy objekt musel uvolnit rucne procedurou Free() inak spadla cela aplikacia, take nieco sa mi v C++ este nestalo, preco?
4. kedy pouzit shared_pointery
5. aku knihu o C++ mi viete doporucit? Idealne aby bola podrobna, aktualna (C++11).
1. Stack volíš vtedy, keď nepotrebuješ, aby tá trieda žila dlhšie. Heap zasa v tých ostatných prípadoch.
2a. Inštancia objekt1 je alokovaná na stacku. Po opustení bloku je automaticky uvoľnená.
2b. Inštancia objekt2 je alokovaná v heape. Po opustení bloku zostáva v pamäti.
2c. Inštancia triedy je alokovaná na stacku, pričom v objekt3 je uložený smerník na túto inštanciu. Po opustení bloku je inštancia uvoľnená.
3. Pamäť uvoľňuješ vtedy, keď už s daným objektom nepotrebuješ pracovať. V C++ sa pamäť uvoľňuje automaticky len v prípade, že je objekt na stacku. Ak alokuješ v heape, tak musíš uvoľňovať podobne ako v Delphi.
4. shared_ptr použiješ vtedy, keď chceš, aby sa inštancia automaticky uvoľnila vtedy, keď ju už nikto nepoužíva. Vďaka počítaniu referencií sa pamäť uvoľní automaticky. Je to v podstate to isté, ako interfejsy v Delphi.
Kľúčovému slovu auto by som sa vôbec nevyhýbal. Namiesto zápisov typu "std::map<std::string, std::map<std::string, std::string> >::iterator it" vo for cykloch použiješ "auto it". V C++ by som práveže uprednostňoval všetky štandardné vlastnosti jazyka, ako sú shared_ptr, unique_ptr, move constructory a podobne. Keď to zvláda VS2013 a gcc, tak nie je čo riešiť.
BTW. ak pominiem to hardcore s tym iteratorom, ty by si napisal namiesto
Motorka x;
auto x = Motorka();
?
2x viac pismen. Navyse je to matuce a nejasne (neviem okamzite ci to Motorka() je trieda alebo nejak funkcia o 3 strany dalej alebo jakeho svateho vynalez. Mysli aj na toho kto to bude citat o rok po tebe... :)
V tomto prípade by som to napísal normálne. Ale tie iterátory sú pre auto ako stvorené.
Je to mozne, ja som konzerva, taketo veci ma zasadne ani nenapadnnu (a napr. na poslednu vec ktoru som robil pred rokom na VC++ bola aby to slo aj na Win98 :). S novymi MS kravinami compilermi ti ten vytvor nepojde ani na XP, nie to este na 98 :)
Neviem ci tam je kriticke jaky typ pouzijes u iteratoru, ja by som sa vyhol aj samotnemu iteratoru a robil to nejak konzervativne :D Ok to je fuk. Este ma napada dalsia vec, a to je overloaded funkcie, povedzme ze mam
Fcia1(int* a);
Fcia1(char* a);
int x;
Fcia1(&x); // pohoda
auto y;
Fcia1(&y); // ?????
:)
To sa nedá tak, že deklaruješ iba auto y. Musí sa použiť initializer, aby bolo z čoho ten typ možné určiť. Podobne ako var v C#.
auto y = NULL;
Fcia1(y);
Napr.
int x; // chcem robit s int
x=CudziaFunkcia(); // ak nevracia int ale napr. int* tak dostanem error apod
auto x=CudziaFunkcia(); // nedostanem error, neviem s cim vlastne pracujem, aj ked sice mozem dostat error dalej, ale ak napr. pri low level veciach pretypujem hned x napr na int* ptz chcem pristupit na adrtesu ktoru mi vratil niekto ako cislo, nedostatem error ziaden. Apod. Je to odstranenie urcitej kontroly, ak napr. ak je gulas vo funkciach a niekto updatuje cudzie funkcie tak ze vracaju nieco ine apod. Ano da sa to povazovat aj ako vyhoda ze hura ked updatujem cudziu funkciu ze bude vracat nejaku inu nemusim prepisovat aj volajuce funkcie, ale nemusi to byt vzdy bezpecne to pouzivat. Nech si na to dava radsej pozor.
y bude int. void* by to bol vtedy, ak by si spravil "auto y = nullptr".
Keď robíš klasické pretypovanie, tak musíš rátať s tým, že to nie je bezpečné. Pozor si treba dávať pri klasickom pretypovaní, nie pri použití auto.
BTW. nepoznal som to (ja som zakysol u MS 2009), takze vdaka za objasnenie pouzitia napr. u tych iteratorov ;)