.[ ČeskéHry.cz ].
Dealokace
Jdi na stránku 1, 2, 3  Další
 
odeslat nové téma   Odpovědět na téma    Obsah fóra České-Hry.cz -> C / C++
Zobrazit předchozí téma :: Zobrazit následující téma  
Autor Zpráva
Aroidzap



Založen: 14. 11. 2011
Příspěvky: 68

PříspěvekZaslal: 12. červenec 2012, 13:13:39    Předmět: Dealokace Odpovědět s citátem

Ahoj, at se snazim, jak se snazim, nedari se mi tohle dealokovat. Pomuzete mi?

kód:
struct TAG{
   char *type_name;
   int subtags;
   unsigned int start;
   unsigned int end;
   char *parameters;
};

std::vector<TAG> *tag_array = new std::vector<TAG>;


kdyz udelam:

kód:
delete tag_array;


, tak se vektor jevi jako prazdny, v pameti ale zustavaji polozky type_name a parameters. Zkousel jsem to jeste takto:

kód:
for (unsigned int i=0;i<tag_array->size();i++)
{
   delete[] tag_array->at(i).type_name;
   delete[] tag_array->at(i).parameters;
}


ale to mi hazelo chyby


Naposledy upravil Aroidzap dne 12. červenec 2012, 16:06:40, celkově upraveno 1 krát
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Marek



Založen: 28. 07. 2007
Příspěvky: 1782
Bydliště: Velká Morava

PříspěvekZaslal: 12. červenec 2012, 13:27:42    Předmět: Odpovědět s citátem

Jak kontroluješ, že v paměti zůstávají?
_________________
AMD Open Source Graphics Driver Developer
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
perry



Založen: 28. 07. 2009
Příspěvky: 879

PříspěvekZaslal: 12. červenec 2012, 13:32:52    Předmět: Odpovědět s citátem

Nevím, jak to kontroluješ.. jak psal Marek... ale pokud jenom nějakým pohledem na blok paměti, tak to, že něco zůstane ve výpisu bloku paměti neznamená, že to je blbě... Podstatné je, zda je paměť označena jako volná.
_________________
Perry.cz
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovi WWW stránky
if.then



Založen: 13. 04. 2008
Příspěvky: 579

PříspěvekZaslal: 12. červenec 2012, 13:57:32    Předmět: Odpovědět s citátem

Vážně si pořiď nějakou knihu o C++. Jinak se to prostě nenaučíš.

Na tvém přístupu je špatně hodně věcí:
1. std::vector není potřeba alokovat, na začátku je to jenom třída s pár atributy (velikost, kapacita, ukazatel na skutečné pole). Ukazatel má v tomhle případě akorát tu výhodu, že můžeš ukazovanou třídu smazat dřív, než se dostane out-of scope. Nicméně si nedokážu představit moc situací, kdy bys to využil.
2. I když používáš C++, pořád používáš C-style strings (char*). Je to naprosto zbytečné a jenom ti to přidělá spousty a spousty problémů. Použij std::string.
3. Když deletuješ, tak to znamená jenom to, že uvolněná paměť je nedefinovaná pro další použití. Může ti to hodit segmentation fault, vrátit nějaké voloviny, nebo prostě vrátit to, co v paměti bylo předtím (což se většinou stane). Jak říkal perry, hlavní je, že paměť je volná. Většinou se po delete doporučuje nastavit ukazatel na nulu (tj. 0, NULL nebo v C++11 nullptr, jsou v tom drobné rozdíly).
_________________
For guns and glory, go to www.ceske-hry.cz.
For work and worry, execute VC++.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
pcmaster



Založen: 28. 07. 2007
Příspěvky: 1821

PříspěvekZaslal: 12. červenec 2012, 14:09:45    Předmět: Odpovědět s citátem

Presne ako pise if.then (az na tu knihu, toho az takym zastancom nie som, ale prosim).

Destruktor std::vector::~vector() v podstate vyvola std::vector::clear() a ten uvolnuje (vola destruktory pre) kazdu instanciu, ktora v internom poli je. No ale TAG::~TAG() nie je, preto sa len uvolni sizeof(TAG) bytov, no a to je tak cele. Btw sizeof(TAG) je cca 20 (x86), nezavisle na "dlzke" "stringov" type_name, atd.

Musis si uvedomit aj to, ze tvoja trieda TAG (ano, struct == class) ma len implicitny konstruktor a destruktor, nemozes preto predpokladat, ze bude tusit, co ma spravit s clenskymi premennymi typu (char *).
_________________
Off-topic flame-war addict since the very beginning. Registered since Oct. 2003!
Interproductum fimi omne est.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
perry



Založen: 28. 07. 2009
Příspěvky: 879

PříspěvekZaslal: 12. červenec 2012, 15:17:28    Předmět: Odpovědět s citátem

if.then >
citace:
std::vector není potřeba alokovat


Jedině když mám funkci, která vrací pole (ukazatel na std::vector)... a zároveň nechci (nebo nemůžu) aby byl ten vector jako in/out vstupní parametr
Nicméně takových případů moc opravdu není Smile A pochybuju, že zrovna tohle je aktuální případ.

Aroidzap ovšem neuvedl zásadní informace.. jestli v tom TAG je char * myšlen jako "string" .. nebo skutečně ukazatel někam na nějaký string do tabulky stringů... v případě pojmenování TAG by to totiž klidně mohlo být. TAGů mám omezený počet, tak proč je alokovat pořád dokola. Ale jen tipuju Smile

Ad druhý kód:
kód:
delete[] tag_array->at(i)type_name;

- tam chybí za tim at(i) "."
_________________
Perry.cz
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovi WWW stránky
Aroidzap



Založen: 14. 11. 2011
Příspěvky: 68

PříspěvekZaslal: 12. červenec 2012, 16:11:56    Předmět: Odpovědět s citátem

(dik perry, uz jsem to spravil)

Jak to zjistuju? - V loopu, vytvarim tag_array, zapisuju, mazu. Pak se divam na pouzitou pamet. Na to, ze to jsou ty dva char* jsem prisel tak, ze po kazdem loopu je jejich adresa o kus dal a nevraci se na uvolnene misto.

Stringy tady nepouzivam, protoze manipulace s char* by mela byt rychlejsi. (Zatim jsem to teda nemeril, jen jsem to cetl)
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
perry



Založen: 28. 07. 2009
Příspěvky: 879

PříspěvekZaslal: 12. červenec 2012, 16:31:19    Předmět: Odpovědět s citátem

char * je o něco rychlejší... ale zálaží samozřejmě co s tím děláš.
Napsal jsem si nad char * vlastní string třídu používající klasické new[delka_retezce] a v testech mi vyšla rychleji než std::string.. navíc mám různě přetížené operátory na konkatenace... pokud to myslíš vážně a nechceš používat std::string, tak doporučuji napsat si vlastní string třídu... dělat pořád s char * je příšerná patlanina, nehledě na funkce typu strncpy apod, které v MSVC při překladu hází warning (dá se sice vypnout, ale není to pak tak pěkné) a doporučují nahrazení M$ funkcemi... ty ovšem jinde (gcc..) nejdou.
Pak jsou tu další řešení jako boost, pouze pro MSVC je soubor knihoven ATL, kde je i string (tyto knihovny používám např. pro hash-mapu.. přenositelnost mi netrápí, protože DirectX).
Psát všechno pomocí char * je blbost Smile a ztráta času, která se za ty ms, co to přinese, nevyplatí.
_________________
Perry.cz
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovi WWW stránky
Aroidzap



Založen: 14. 11. 2011
Příspěvky: 68

PříspěvekZaslal: 12. červenec 2012, 16:42:06    Předmět: Odpovědět s citátem

No kdyz tech ms bude hodne, tak se to vyplati Wink
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
manutara



Založen: 02. 01. 2012
Příspěvky: 81
Bydliště: Kosice SVK

PříspěvekZaslal: 12. červenec 2012, 16:56:49    Předmět: uuuups Odpovědět s citátem

sorry, ale neda mi.

hmm, pokial program pada, lebo ma bordel v pamati tak tie usetrene
``ms'' sa neprejavia ani nahodou Wink

zatim...
_________________
hadam to OpenGL este par rokov prezije
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Aroidzap



Založen: 14. 11. 2011
Příspěvky: 68

PříspěvekZaslal: 12. červenec 2012, 17:00:24    Předmět: Odpovědět s citátem

Vypada to snad, ze se nesnazim o to, abych v pameti ten bordel nemel? Confused

Zkousel jsem to nejak udelat pomoci destruktoru ale to se mi nepovedlo... nenapada vas neco?
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
if.then



Založen: 13. 04. 2008
Příspěvky: 579

PříspěvekZaslal: 12. červenec 2012, 17:48:41    Předmět: Odpovědět s citátem

Asi takhle.

Uchovávat v paměti objekty můžeš třemi způsoby: globálně, na zásobníku nebo na haldě.

S globálními objekty nic neřešíš: na začátku programu se jim prostě zavolá konstruktor, na konci jsou smazány systémem. Nic složitého.

S objekty na zásobníku je to trochu složitější, ty totiž platí jenom v programovém bloku (v C++ je ohraničen složenými závorkami {}). To znamená, že když se exekuce kódu dostane na {, na vrcholu zásobníku vytvoří místo pro tyhle objekty. Když se dostane na odpovídající }, zavolá objektům destruktory a vrchol zásobníku smaže. (Mluvíme o tzv. out-of-scope.)

Objekty na haldě vytváříš tak, že máš ukazatel (globální nebo na zásobníku) a zavoláš funkci, která na haldě vytvoří objekt(y) určitého typu (typicky malloc, new /new navíc volá konstruktor/) a vrátí adresu prvního z nich. Ty si ji uložíš do ukazatele a pak s adresovanou pamětí pracuješ.

Ale pozor. Systém správy paměti neví, kterou paměť na haldě ještě používáš a kterou už ne. Když jsi tedy hotov, zavoláš na ukazatel inverzní funkci, tj.
malloc->free
new->delete
new[]->delete[]
a podobně. Teď už systém ví, kterou paměť už nepoužíváš a může ji přidělit, když o to někdo požádá. Hurá! V ukazatelích, které ukazovaly na tyto objekty, nicméně zůstává tato hodnota. Na to si musíš dávat pozor.

Pokud v tomhle nebudeš důsledný, mohou se ti přihodit různé pěkné věci. Takže si dávej pozor Wink .

EDIT: A to, jestli std::string je rychlostně horší, to neřeš. Poznáš to, když budeš real-time pracovat s desetimiliony řetězců, ale jinak to fakt nemá vliv. Jak podotkl Donald Knuth:
Donald Knuth napsal:
Premature optimization is the root of all evil.

_________________
For guns and glory, go to www.ceske-hry.cz.
For work and worry, execute VC++.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
manutara



Založen: 02. 01. 2012
Příspěvky: 81
Bydliště: Kosice SVK

PříspěvekZaslal: 12. červenec 2012, 17:57:35    Předmět: Odpovědět s citátem

-> if.then

ty by si mal prednasat, fakt velmi pekne vysvetlene a hlavne ``po lopate''
_________________
hadam to OpenGL este par rokov prezije
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Aroidzap



Založen: 14. 11. 2011
Příspěvky: 68

PříspěvekZaslal: 12. červenec 2012, 18:00:24    Předmět: Odpovědět s citátem

Jinak teoreticky, kdyz nahodou neprovedu delete (z nepozornosti, ne zamerne), uvolni se pamet sama ne?

... povedlo se mi ten problem vyresit. Problem byl ale v alokaci... moc to nechapu, ale tak jede to no... alokoval jsem pro ty char* o jeden char min nez jsem zapisoval. Zahadou tedy je, proc to delalo problemy pri dealokaci, a ne pri zapisu na nealokovane misto...
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
manutara



Založen: 02. 01. 2012
Příspěvky: 81
Bydliště: Kosice SVK

PříspěvekZaslal: 12. červenec 2012, 18:07:24    Předmět: Odpovědět s citátem

citace:
Jinak teoreticky, kdyz nahodou neprovedu delete (z nepozornosti, ne zamerne), uvolni se pamet sama ne?


v principe ano, po skonceni programu to uprace system. ale kto narobi
bordel mal by po sebe aj upratat este pred ukoncenim. niekedy ti ta,
neuvolnena, pamat moze chybat.

citace:
... povedlo se mi ten problem vyresit. Problem byl ale v alokaci... moc to nechapu, ale tak jede to no... alokoval jsem pro ty char* o jeden char min nez jsem zapisoval. Zahadou tedy je, proc to delalo problemy pri dealokaci, a ne pri zapisu na nealokovane misto...


inak by si tu mohol dat aj to riesenie, mozno to niekomu v buducnosti pomoze
ked bude prehladavat toto forum...
_________________
hadam to OpenGL este par rokov prezije
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Zobrazit příspěvky z předchozích:   
odeslat nové téma   Odpovědět na téma    Obsah fóra České-Hry.cz -> C / C++ Časy uváděny v GMT + 1 hodina
Jdi na stránku 1, 2, 3  Další
Strana 1 z 3

 
Přejdi na:  
Nemůžete odesílat nové téma do tohoto fóra
Nemůžete odpovídat na témata v tomto fóru
Nemůžete upravovat své příspěvky v tomto fóru
Nemůžete mazat své příspěvky v tomto fóru
Nemůžete hlasovat v tomto fóru


Powered by phpBB © 2001, 2005 phpBB Group


Vzhled udelal powermac
Styl "vykraden" z phpBB stylu MonkiDream - upraveno by rezna