abclinuxu.cz AbcLinuxu.cz itbiz.cz ITBiz.cz HDmag.cz HDmag.cz abcprace.cz AbcPráce.cz
AbcLinuxu hledá autory!
Inzerujte na AbcPráce.cz od 950 Kč
Rozšířené hledání
×
    dnes 11:55 | Upozornění

    V neděli 11. října proběhne rotace klíče kořenové zóny. Podruhé v historii. Ondřej Filip na blogu CZ.NIC: "Pokud je pro Vás DNS protokol spíše výzva, ale přesto spravujete nějakou síť či DNS resolver, zkuste si jednoduchý test, který připravila firma Cloudflare na této adrese. Obzvláště zbystřit byste měli, pokud uvidíte nějaká červená políčka."

    Ladislav Hagara | Komentářů: 3
    dnes 09:55 | IT novinky

    Vláda Spojených států se rozhodla vyřadit americkou softwarovou společnost Microsoft a několik dalších velkých technologických podniků z programu, který umožňuje kvalifikovaným zahraničním pracovníkům získat povolení k trvalému pobytu. Oznámila to včera administrativa amerického prezidenta Donalda Trumpa. Opatření zdůvodnila rozsáhlým zneužíváním programu, který je dlouhodobě terčem kritiky ze strany Trumpových příznivců, neboť prý znevýhodňuje americké pracovníky.

    Ladislav Hagara | Komentářů: 10
    dnes 09:44 | IT novinky

    Datové centrum největší ruské technologické společnosti Jandex v Rjazaňské oblasti se stalo cílem dronového útoku a zastavilo provoz. Jandexu se někdy přezdívá „ruský Google“. Provozuje nejoblíbenější internetový vyhledávač v Rusku nebo aplikace pro objednávky jídla a taxi. Využívají jej desítky milionů lidí v rusky mluvících zemích.

    Ladislav Hagara | Komentářů: 8
    dnes 09:33 | Nová verze

    Francouzská společnost Mistral AI představila Mistral Large 4 (interně přezdívaný 'le Chonk', volně přeloženo 'pořádný macek'), 'open-weight multimodální hybridní instruct-and-reasoning model s architekturou granulárního MoE, nativně podporující více jak 160 jazyků'. Model má přes jeden bilión parametrů, z nichž při práci využívá 49 miliard, kontextové okno o délce milion tokenů a obrazový enkodér o 1,6 miliardách parametrů.

    … více »
    ❗Červivý Hřib krade❗ | Komentářů: 0
    dnes 03:22 | Nová verze

    Svobodný multiplatformní herní engine Bevy napsaný v Rustu byl vydán ve verzi 0.20. Díky 227 přispěvatelům.

    Ladislav Hagara | Komentářů: 0
    dnes 03:11 | Komunita

    Simon Long oznámil Raspberry Pi Desktop pro PC a Mac s Intelem postavený na aktualizovaném Debianu 13 Trixie. S klientem Raspberry Pi Connect pro vzdálenou správu. Ke stažení je vedle Raspberry Pi OS pro Raspberry Pi.

    Ladislav Hagara | Komentářů: 0
    včera 21:33 | Zajímavý projekt

    ESP32-C3 adblock přemění lacinou vývojovou desku ESP32‑C3 na samostatný DNS blokovač nejenom reklamních domén, minimalistickou alternativu k populárnímu Pi-hole. ESP32-C3 adblock místo objemných názvů domén ukládá jejich 40-bitové FNV-1a hashe do flash paměti, které pak binárně prohledává, kontrola jedné domény trvá přibližně 10 milisekund. Blocklist pojme až 537 tisíc domén a lze jej spravovat přes webové rozhraní. Projekt zatím

    … více »
    ❗Červivý Hřib krade❗ | Komentářů: 0
    včera 21:00 | Zajímavý software

    ArtCraft je sada open source aplikací pro práci s obrázky a videi "inspirovaných" aplikacemi od Adobe. Napsaných v Rustu. Pro MacOS, Windows i Linux. Běží také ve webovém prohlížeči. Aktuálně se jedná o 7 aplikací: PhotoCraft (Photoshop), VectorCraft (Illustrator), FilmCraft (Premiere Pro), LightCraft (Lightroom), PdfCraft (Acrobat), EffectCraft (After Effects) a DesignCraft (InDesign). Zdrojové kódy jsou k dispozici na GitHubu.

    Ladislav Hagara | Komentářů: 8
    včera 16:33 | Zajímavý software

    Strands Decider 2B je malý open-source model s 2 miliardami parametrů, určený k rychlé klasifikaci vstupů a rozhodování mezi možnostmi, generující odpovědi ve stylu modelu Jev. Strands dosáhl přibližně 72% shody s Jevem na veřejné testovací sadě JevBench (tento benchmark pochopitleně nepředstavuje přímé srovnání s modelem Jev). Zdrojové kódy jsou k dispozici na GitHubu pod licencí Apache-2.0, váhy modelu na Hugging Face.

    ❗Červivý Hřib krade❗ | Komentářů: 4
    včera 16:22 | Upozornění

    Ve věku 90 let zemřela americká softwarová inženýrka Margaret Hamiltonová, která vedla tým, jenž vyvíjel letový software pro program Apollo amerického Národního úřadu pro letectví a vesmír (NASA).

    Ladislav Hagara | Komentářů: 7
    Které desktopové prostředí na Linuxu používáte?
     (9%)
     (7%)
     (4%)
     (21%)
     (29%)
     (8%)
     (5%)
     (2%)
     (14%)
     (20%)
    Celkem 2818 hlasů
     Komentářů: 31, poslední 13.8. 00:27
    Rozcestník

    Dotaz: Dynamicky alokované pole struktur

    Beda0 avatar 11.5.2013 15:49 Beda0 | skóre: 29
    Dynamicky alokované pole struktur
    Přečteno: 1756×
    Zdravím,

    mam dynamicky alokované pole struktur, které obsahují další struktury s 2D poli floatů a dašlích věcí a nějak jsem se do toho zamotal. Začínalo to poměrně jednoduše, ale pak se to postupně narostlo. Potřeboval bych poradit, jestli to uvolňuju správně a jestli je zvolené řešení vůbec vhodné.

    Je to psané v C++, takže to je rozházené do tříd, zde pro jednoduchost jsou jen funkce. Data alokuju dynamicky až v readData(), protože na začátku čtení dat netušim, kolik jich bude a může jich být docela dost - v řádu tisíců struktur Data.
    
    typedef struct {
        float** fDataA; //2D array of ...
        ...
    }Data2;
    
    typedef struct{
     float a[3];
     int b[4];
     int c;
     string string;
     Data2 data2;
     ...
    } Data;
    
    int allocateData(Data **data,...){
      *data = (Data*) malloc( pocetDat * sizeof(Data));
      for(int y = 0;y < pocetDat; y++){
        (*data)[y].data2.fDataA = (float**) malloc((*data)[y].data2.pocetDat2*sizeof(float*));
        
        for(int i = 0;i < pocetDat2;i++){
          (*data)[y].data2.fDataA[i] = (float*) malloc(pocetDat3*sizeof(float));
        }
      }
      ... //dalsi dynamicke alokace, overeni, jestli se to opravdu alokovalo...
    }
    
    int freeData(mainData **data){
      for(int y = 0;y < pocetDat; y++){
        for(int i = 0;i < pocetDat2; i++){
          free((*data)[y].data2.fDataA[i]);
        }
      }
      free(*data);
    }
        
    readData(Data **data,...){
       ...
       allocateData(data,...);
       ...
       //nactu hodnoty do data
       ...
    }
    
    main(){
       Data *data;
       ...
       readData(&data,...);
       ...
       printf("integer %i",data[2586].b[4]);
       freeData(&data);
    }
    

    Odpovědi

    Josef Kufner avatar 11.5.2013 17:30 Josef Kufner | skóre: 70
    Rozbalit Rozbalit vše Re: Dynamicky alokované pole struktur
    Příliš intenzivní používání malloc je značně neefektivní. Alokuj si velký kus paměti najednou, který ti bude většinou stačit a kdyby náhodou ne, tak přialokuj další. Nebo raději použij už hotový alokátor. Ten rozdíl ve výkonu je celkem značný.

    Co se samotného alokování týče (ať už malloc nebo něco jiného), od toho jsou konstruktory a destruktory. A vůbec, co se ti nelíbí na new?
    Hello world ! Segmentation fault (core dumped)
    Beda0 avatar 11.5.2013 18:00 Beda0 | skóre: 29
    Rozbalit Rozbalit vše Re: Dynamicky alokované pole struktur
    Díky za reakci. Takže je vhodnější spočítat, kolik paměti budu potřebovat, což je v době volání allocateData známo a pak použít *data = (Data*) malloc(spocitanaVelikost);?

    Malloc je použit protože to původně bylo v C a až do teď jsem nějak nepřemýšlel v čem se vlastně tak liší od New.

    Jenže Data a Data2 jsou struktury, ne třídy, takže jejich konstruktory použít nemůžu i když by se tím asi dost věcí zjednodušilo.

    Vlasně možná by nemuseli být - budu k tomu muset udělat binding do Pythonu, který znám jen z rychlíku, ale předpokládal jsem, že bude vhodnější nechat data ve strukturách, než ve třídách, což asi nemusí být pravda. Struktura Data se předává mezi knihovnou a programem a nějak jsem předpokládal, že bude vhodnější předávat data ve struktuře a ne ve třídě, co je taky asi jedno....
    11.5.2013 18:20 chrono
    Rozbalit Rozbalit vše Re: Dynamicky alokované pole struktur
    Ak tie údaje nie sú príliš veľké, tak sa môže priamo cez CPython vytvárať pythonovský objekt. Prípadne, ak spracovanie nie je príliš zložité, môže sa k tej knižnici pristupovať cez ctypes a údaje sa budú spracovávať až v Python.
    11.5.2013 18:35 Jan Trávníček | skóre: 10 | blog: ehonza | Existuje
    Rozbalit Rozbalit vše Re: Dynamicky alokované pole struktur
    Proč by si nemohl v C++ použít konstruktor a destruktor u struktury?
    To mess up a Linux box, you need to work at it; to mess up your Windows box, you just have to work on it.
    11.5.2013 18:57 potato
    Rozbalit Rozbalit vše Re: Dynamicky alokované pole struktur
    Protože strukturou myslí nejspíš plain-old-data[*], stejně jako normální lidi, kteří když má něco konstruktor a destruktor, tak tomu řeknou třída.

    Na rozdíl od jazykových právníků, kteří samozřejmě vědí, že ten nejdůležitější rozdíl mezi stukturou a třídou v C++ je marginální, tedy výchozí přístupová práva ke členům, a pak se diví, že se s nikým nedomluví.

    [*] Zde experti na C+11 zajásají, protože dostali příležitost vysvětlit, jak tam byl tento koncept rozveden a rozdělen, etc.
    11.5.2013 20:00 Jan Trávníček | skóre: 10 | blog: ehonza | Existuje
    Rozbalit Rozbalit vše Re: Dynamicky alokované pole struktur
    Což ovšem neodpovídá na otázku zda by díky té možnosti něco nezlehčilo/nezjednodušilo.
    To mess up a Linux box, you need to work at it; to mess up your Windows box, you just have to work on it.
    11.5.2013 22:19 potato
    Rozbalit Rozbalit vše Re: Dynamicky alokované pole struktur
    To už nedovedu posoudit z hlediska možnosti vytváření bindingů z C++ do jiných jazyků, protože to nesleduji zase tak podrobně -- občas napíši něco ručně, ale jinak je dělám hlavně z C pomocí g-ir. Každopádně bindingy C++ tříd vyžadují obecně dost jiné přístupy než POD + funkce.
    Beda0 avatar 12.5.2013 09:40 Beda0 | skóre: 29
    Rozbalit Rozbalit vše Re: Dynamicky alokované pole struktur
    Struktury jsou bez konstruktorů proto, že jich je tam víc a některé z nich nemam pod kontrolou - používají se i jinde a nemůžu je měnit. Proto mi přišlo vhodné ukládat všechno do struktur a ne půlku do struktur a půlku do tříd.

    Na druhou stranu nemám pod kontrolou jen struktury výrazně jednodušší, do kterých se ukládají dost odlišná data, proto by bylo možné v tomto případě použít třídy, ale narážím na problém s bindingem, který může a nemusí být reálný, zatím jsem neměl čas to dopodrobna studovat.

    Vím, že jediný rozdíl mezi strukturou a třídou v C++ je to, že struktura má členy implicitně public, označil jsem to nepřesně přesně ve smyslu jak píše potato.
    Beda0 avatar 12.5.2013 10:39 Beda0 | skóre: 29
    Rozbalit Rozbalit vše Re: Dynamicky alokované pole struktur
    Takže jsem upravil a používám new/delete místo malloc/free. Vím, že by šlo vše optimalizovat použitím fDataA[i*pocetDat2+y] místo fDataA[i][y],ale podle mě při takovém množství dat ta malá úspora paměti na úkor přehlednosti nemá cenu. Rychlost alokace je v porovnání s rychlostí načítání dat zanedbatelná. Jediný problém tuším v tom, že data nebudou v paměti za sebou, což nedokážu posoudit, jaký může mít vliv.
    int allocateData(Data **data,...){
      *data = new Data[pocetDat];
      for(int y = 0;y < pocetDat; y++){
         (*data)[y].data2.fDataA = new float*[pocetDat2];
         for(int i = 0; i < pocetDat2; ++i){
            (*data)[y].data2.fDataA[i] = new float[pocetDat3];
         }
      }
      ...
    }
    
    int freeData(Data **data,...){
      for(int y = 0;y < pocetDat; y++){
        for(int i = 0;i < pocetDat2; i++){
          delete [] (*data)[y].data2.fDataA[i];
        }
        delete [] (*data)[y].data2.fDataA;
      }
      delete [] *data;
    }
    12.5.2013 11:51 TonyMi
    Rozbalit Rozbalit vše Re: Dynamicky alokované pole struktur
    Když už to je C++, tak bych použil std::vector. Kód je pak mnohem čistější, dealokace je často "bez práce" a rychlost nebude nižší (pokud velikost znáte stačí použít reserve či resize). Navíc se kdykoliv můžete zeptat na počet prvků a nemusíte si jej spravovat sám.
    12.5.2013 14:33 Jardík
    Rozbalit Rozbalit vše Re: Dynamicky alokované pole struktur
    Mé atomy souhlasí. Děláš to v C++, použij std::vector a vyser se na pitomý malloc/free. Např. podívej, jak se ti zjednoduší uvolnění paměti, jeden pitomej clear() na std::vector<Data> a vše ostatní jde samo. A i když ten clear nezavoláš, vše se stejně uvolní v destruktoru vectoru pro tebe, úpně bez práce, bez jediného řádku kódu. Příklad (netestovaný, na rychlo spatlaný, bez přemýšlení, možná s chybama):
    struct Data2
    {
      std::vector<std::vector<float>> fDataA;
      // ...
    };
    
    struct Data
    {
      float a[3];
      float b[4];
      int c;
      string string;
      Data2 data2;
      // ...
    };
    
    int allocateData(std::vector<Data>& data, ...)
    {
      data.resize(pocetDat);
      
      for (size_t y = 0; y < pocetDat; ++y)
      {
        Data& dy = data[y];
        
        dy.data2.fDataA.resize(pocetDat2);
        for (size_t i = 0; i < pocetDat2; ++i)
        {
          dy.data2.fDataA[i].resize(pocetDat3);
        }
      }
      
      // blabla
    }
    
    int freeData(std::vector<Data>& data)
    {
      // aneb vyser se na malloc a free
      data.clear();
    }
    
    
    Beda0 avatar 12.5.2013 17:02 Beda0 | skóre: 29
    Rozbalit Rozbalit vše Re: Dynamicky alokované pole struktur
    Nojo, proč mě to nenapadlo? Nějak mi nedošlo, že už nejsem v C a mam všechny ty úžasný věcičky z C++. Díky.
    Beda0 avatar 12.5.2013 18:42 Beda0 | skóre: 29
    Rozbalit Rozbalit vše Re: Dynamicky alokované pole struktur
    S tou paměťovou náročností std::vector to nebude zas tak růžový, jak všude čtu - s vektorama si to vezme o 5 MB víc - 67 místo 62 - a to jsem vektory použil jen na floaty, ne na celý struktury. Mam 25920 struktur data, každá obsahuje 3 pole floatů 4*25. Měřeno "od oka" ve správci procesů. Připadá mi to docela vysoká cena za zjednodušení.

    Testuju na x86_64, ale poběží to na ARMu s né zrovna moc pamětí, takže nějaký šetření je na místě.
    12.5.2013 20:02 Jardík
    Rozbalit Rozbalit vše Re: Dynamicky alokované pole struktur
    Tak s vectorem je to tak, že tam pravděpodobně bude držet nějaký dvě hodnoty (počet prvků a velikost naalokovaného bufferu) a nějaký ukazatel. Proto asi vector<vector<float>> nebude udeální, ale pro jednoduchost jsem to tam narval. Lepší by asi byl vector<float> s velikostí cols*rows a index počítat jako row*cols+col nebo tak něco.
    12.5.2013 21:36 Šangala | skóre: 56 | blog: Dutá Vrba - Wally
    Rozbalit Rozbalit vše Re: Dynamicky alokované pole struktur
    Jen pro doplnění, následný kód paměť neuvolní (jen k poznámce „aneb vyser se na malloc a free“).
    int freeData(std::vector<Data>& data)
    {
      // aneb vyser se na malloc a free
      data.clear();
    }
    
    optimističtější varianta by musela vypadat asi takto nějak:
    int freeData(std::vector<Data>& data)
    {
      data.clear();
      // aneb vyser se na malloc a free
      std::vector<Data> tmp;
      data.swap(data);
    }
    
    Jinak vector určitě jo, nicméně pokud to má mít i malé paměťové nároky, tak bohužel jen jeden a počítat si to růčo a přistupovat k prvkům přes at(), ale zamyslel bych se nad tím, jestli mi opravdu vadí použít vector vector-ů při drobném navýšení nároků. Kdyby se jednalo o miliony a více záznamů, tak to má význam, ale tísíce znamená 10tis, což je asi 280KB navíc).
    To, že trpíš stihomamem, ještě neznamená, že po tobě nejdou. ⰞⰏⰉⰓⰀⰜⰉ ⰗⰞⰅⰜⰘ ⰈⰅⰏⰉ ⰒⰑⰎⰉⰁⰕⰅ ⰏⰉ ⰒⰓⰄⰅⰎ ·:⁖⁘⁙†
    12.5.2013 22:02 Šangala | skóre: 56 | blog: Dutá Vrba - Wally
    Rozbalit Rozbalit vše Re: Dynamicky alokované pole struktur
    Jeda sorry, opravička:
    int freeData(std::vector<Data>& data)
    {
      // aneb vyser se na malloc a free
      data.clear();
      std::vector<Data>& tmp;
      data.swap(tmp);
    }
    To, že trpíš stihomamem, ještě neznamená, že po tobě nejdou. ⰞⰏⰉⰓⰀⰜⰉ ⰗⰞⰅⰜⰘ ⰈⰅⰏⰉ ⰒⰑⰎⰉⰁⰕⰅ ⰏⰉ ⰒⰓⰄⰅⰎ ·:⁖⁘⁙†
    Beda0 avatar 12.5.2013 22:40 Beda0 | skóre: 29
    Rozbalit Rozbalit vše Re: Dynamicky alokované pole struktur
    S těma tisícema jsem to trošku podcenil - těch floatů je na datech, na kterých to testuju 26000*3*4*25 = 7 800 000. (26000 struktur Data, každá obsahuje 3 pole floatů, každé o velikost 4*25) Paměťová náročnost 2D polí je bohužel výrazná, viz níže. Zítra si s tím ještě zkusím pohrát a uvidím, jaký bude rozdíl použití float vs std::vector. Díky.
    Beda0 avatar 12.5.2013 22:42 Beda0 | skóre: 29
    Rozbalit Rozbalit vše Re: Dynamicky alokované pole struktur
    Ty data toho obsahují daleko víc, než 3 pole floatů, ale teď se zabývám jen těma třema polema....
    12.5.2013 23:29 Šangala | skóre: 56 | blog: Dutá Vrba - Wally
    Rozbalit Rozbalit vše Re: Dynamicky alokované pole struktur
    Jestli to není třeba vhodné na:
    typedef struct{
      float ttt[3][4][25];
    }myrec;
    
    std::vector<myrec> data;
    
    To, že trpíš stihomamem, ještě neznamená, že po tobě nejdou. ⰞⰏⰉⰓⰀⰜⰉ ⰗⰞⰅⰜⰘ ⰈⰅⰏⰉ ⰒⰑⰎⰉⰁⰕⰅ ⰏⰉ ⰒⰓⰄⰅⰎ ·:⁖⁘⁙†
    Beda0 avatar 12.5.2013 22:28 Beda0 | skóre: 29
    Rozbalit Rozbalit vše Re: Dynamicky alokované pole struktur
    To mě nikdy nenapadlo, že 2D pole mají tak velkou režiji - se std::vector<float> to má 56MB, s float* 55.5MB - rozdíl necelých 0.5MB, ale 11MB, resp. 6MB oproti použití 2D polí. Nicméně při použití pouze jednorozměrných polí se vytrácí výhoda std::vector, protože stejně musím udržovat informace o velikostech kvůli ručnímu počítání iterací float[i*size1+y]. .size() je mi k ničemu. Navíc všechny ostatní data mám ve standardních polích a není vhodné mít půlku tak a půlku tak.

    Kdybych všechny data uložená v polích převedl na std::vector, tak bude rozdíl v paměťové náročnosti větší než nynějších 0.5MB a práci mi to neulehčí (kromě alokace a uvolnění paměti) vůbec v ničem.
    12.5.2013 23:04 Šangala | skóre: 56 | blog: Dutá Vrba - Wally
    Rozbalit Rozbalit vše Re: Dynamicky alokované pole struktur
    Příloha:
    Dej přesně všechny podmínky, ten rozdíl je, že vector jestli má s spou režii, ukazatel, kapacita, velikost. S resize můžeš přidat více paměti než chceš viz příloha (kompilovatelná g++ kuk.cpp -o kuk), ono vector je super, ale zrovna ve správě paměti se lehce naseká spousta chyb (platí pro celou stl).
    Jde o to co má pevnou délku a co nemá, z toho je třeba u takové aplikace vyjít.
    To, že trpíš stihomamem, ještě neznamená, že po tobě nejdou. ⰞⰏⰉⰓⰀⰜⰉ ⰗⰞⰅⰜⰘ ⰈⰅⰏⰉ ⰒⰑⰎⰉⰁⰕⰅ ⰏⰉ ⰒⰓⰄⰅⰎ ·:⁖⁘⁙†
    Beda0 avatar 13.5.2013 10:47 Beda0 | skóre: 29
    Rozbalit Rozbalit vše Re: Dynamicky alokované pole struktur
    Díky za osvětlení problematiky. STL jsem nikdy moc nepoužíval, takže tady mam dost mezery.

    Mno, je z toho tady už docela zmatek, takže stav, v jakym to je teď:
    typedef struct {
        u64 neco;
        u8 neco2;
        u8 neco3;
        float pole1[4];
        float pole2[4];
        ... /dalsi data - celkem 846B dat ulozenych vetsinou ve ve 4 prvkovych float polich s pevnou delkou
    
        //nasleduje pet poli o ktere mi ted jde predevsim - na testovacich datech jsou tri
        //z nich o velikosti 4*25 a dve prazdne. Maximalne muze v soucasne dobe mit kazde 
        //velikost 4*50. Velikost poli neznam v dobe kompilace, ale v dobe volani allocateData
        //uz jo a nikdy se potom nemeni.
        float *dulezitePole1; /**< 2D array of ... */
        float *dulezitePole2; /**< 2D array of ... */
        float *dulezitePole3; /**< 2D array of ... */
        float *dulezitePole4; /**< 2D array of ... */
        float *dulezitePole5; /**< 2D array of ... */
    
    } Data;
    allocateData(Data **data,...){
        //pocetDat = pocet struktur Data je na testovacich datech 26000,
        //v realu muze byt vyrazne min, ale i o dost vic.
        *data = new Data[pocetDat];
        
        for(int y = 0;y<pocetDat;y++){
            (*data)[y].dulezitePole1 = new float[pocetDat21 * pocetDat3];
            (*data)[y].dulezitePole2 = new float[pocetDat22 * pocetDat3];
            (*data)[y].dulezitePole3 = new float[pocetDat23 * pocetDat3];
            (*data)[y].dulezitePole4 = new float[pocetDat24 * pocetDat3];
            (*data)[y].dulezitePole5 = new float[pocetDat25 * pocetDat3];
        }
    }
    
    
    Když jsem místo float *dulezitePole1 zkoušel std::vector<float> dulezitePole1 a ve funkci allocateData použil dulezitePole1.resize(pocetDat21 * pocetDat3); byla spotrebovana pamet jen o 0.5 MB vetsi nez pri pouziti float* a new.

    Jenže použití std::vector mi nepřineslo žádný viditelný užitek - stejně jsem si musel iterovat a pamatovat velikosti sám, protože dulezitePole1.size() je mi k ničemu. Navíc zde dochází k tomu, že většina polí je float[4] a 5 polí je std::vector, což je matoucí - tu knihovnu nebudu používat jen já.

    Když jsem použil std::vector na všehny 4 prvkové pole floatů ve struktuře Data (je jich 50), tak paměťová náročnost vzrostla o 11,5MB.

    Beda0 avatar 13.5.2013 11:11 Beda0 | skóre: 29
    Rozbalit Rozbalit vše Re: Dynamicky alokované pole struktur
    Odpovídající freeData:
    int freeData(Data **data){
        for(int y = 0;y < pocetDat; y++){
          delete [] (*data)[y].dulezitePole1;
          delete [] (*data)[y].dulezitePole2;
          delete [] (*data)[y].dulezitePole3;
          delete [] (*data)[y].dulezitePole4;
          delete [] (*data)[y].dulezitePole5;
        }
        delete [] *data;
        return 0;
    }
    
    13.5.2013 18:45 TonyMi
    Rozbalit Rozbalit vše Re: Dynamicky alokované pole struktur

    Když místo resize použijete reserve, tak se sice paměť naalokuje, ale size bude ukazovat reálný počet prvků a přidávat pak budete pomocí push_back.

    Na ta pole float[4] skutečně nemá cenu std::vector používat. Nevím co s těmi poli děláte, možná by zpřehlednění pomohl typedef či lépe nějaká obalující třída (pokud to jsou třeba quatermiony, tak se do obalující třídy dají přidat metody pro různé operace nad nimi, přetížit operátory a podobně).

    Padesát čtyrprvkových polí ve struktuře mi trochu zavání špatným návrhem, opravdu to potřebujete takto udělat? Nestačilo by jedno padesátiprvkové pole tříd se čtyřmi floaty uvnitř?

    Z mého pohledu má std::vector hlavní výhody v tom, že si nemusím udržovat počet prvků, v dealokaci a v čistotě kódu. Při vývoji velkých aplikací se mi to osvědčilo. Pokud tyto tři aspekty hodnotíte jinak, asi pro Vás nemá std::vector význam.

    Beda0 avatar 13.5.2013 19:43 Beda0 | skóre: 29
    Rozbalit Rozbalit vše Re: Dynamicky alokované pole struktur
    Díky za postřehy.

    Data obsahují údaje o různých vlastnostech - těch vlastností je 50, proto 50 polí. Každá vlastnost je ukládaná pro 4 "jednotky", proto 4 prvky každého pole. Jednou ty data načtu a pak je zobrazuju - podle vlastností pro všechny jednotky naráz - tzn. např. v grafu zobrazím jednu vlastnost pro všechny 4 jednotky. Návrh určitě není ideální, proto se také tady ptám, ale nenapadá mě, jak to udělat jednodušeji při zachování přehlednosti. Jsou to jednoduchá data, takže nad nimi žádné operace provádět nepotřebuju - jen je nějak zobrazit a o to se stará jiná aplikace.

    Jenže já o tu největší přednost std::vector - to, že si nemusim udržovat počet prvků - přijdu, když použiju jednorozměrné pole pro uložení dat z matice s "dynamickou" velikostí (kvůli úspoře paměti) - samotné .size() je mi tady k ničemu, protože stejně musím iterovat sám - (*data)[y].dulezitePole1[i*pocetDat3 + y]. Při použití std::vector by mi stačilo udržovat informaci o pocetDat3 a druhou velikost dopočítat ze .size(), takhle musím udržovat informace i o dalších 5 velikostech(pocetDat2x). To je pravda. Ale velikosti se dají dopočítat vcelku jednoduchou funkcí z konfiguračních dat, které načítám také, takže si je nemusím pořád pamatovat. Navíc je IMHO už jedno, jestli si pamatuju jednu velikost nebo 6 uložených v jedné struktuře.

    Zjednodušení při alokaci a dealokaci, kterou provádím ve funkcích je minimální. Naprogramuju jednou funkce pro alokaci a dealokaci, které bych musel mít stejně a víc mi to nic nezesložiťuje ani nedělá kód čistší.

    Výše popsané (v tomto konkrétním případě né příliš výrazné) výhody std::vector mi IMHO nevyváží to, že se mi nelíbí mít v jedné struktuře míchané standardní pole se STL kontejnery.

    Abych nebyl špatně pochopen - nemám nic proti std::vector a v Qt s oblibou požívám QVector a podobné kontejnery, jen pro jejich požití v tomhle konkrétním případě nevidím moc důvod, ale je možné, že mi pořád něco uniká...
    Josef Kufner avatar 13.5.2013 21:14 Josef Kufner | skóre: 70
    Rozbalit Rozbalit vše Re: Dynamicky alokované pole struktur
    Takže ty chceš místo std::vector implementovat vlastní kontejner, který bude obsahovat předalokované dvojrozměrné pole a bude umět k němu hezky přistupovat. Nepatlej to dohromady a implementuj kontejner.
    Hello world ! Segmentation fault (core dumped)
    Beda0 avatar 13.5.2013 22:03 Beda0 | skóre: 29
    Rozbalit Rozbalit vše Re: Dynamicky alokované pole struktur

    Jenže std::vector je příliš paměťově náročný, když mam 26000 struktur Data, který sice obsahujou dynamicky alokovaný pole, ale ve všechn 26000 případech odpovídající pole mají stejný rozměr (což sem asi měl zmínit dřív) - takže tady 26000*5 ukládám ve std::vector kromě vlstních dat to samý - velikost + další režii, což mi ve výsledku zvýší paměťovou náročnost a skoro mi to nepomůže.

    Josef Kufner avatar 13.5.2013 23:31 Josef Kufner | skóre: 70
    Rozbalit Rozbalit vše Re: Dynamicky alokované pole struktur
    Čti pozorněji ;-) Povídám místo std::vector.

    Prostě si naprogramuj úsporné, efektivní a snadno použitelné 2D pole přesně takové, jaké potřebuješ. Transformace souřadnic jsem tu už viděl, jen to pěkně zabalit, aby se s tím dalo pracovat. Jeho prvky pak budou nějaké rozumné třídy/struktury/cokoliv, to už jsi tu snad už vyřešil o pár komentářů výše.
    Hello world ! Segmentation fault (core dumped)
    12.5.2013 22:57 lacod
    Rozbalit Rozbalit vše Re: Dynamicky alokované pole struktur
    Neviem ako je mysleny riadok string string; ale ak predpokladame objekt triedy std::string, tak alokovanie instancie struktury data pomocou funckie malloc nie je korektne, pretoze sa nezavola konstruktor triedy std::string. Tu su nejake tipy v C++ bez kontajnerov:
    // vytvorenie pola objektov , !!pouziva def.konstruktor pre Data
    Data *data = new Data[pocetDat]; 
    // dealokovanie objektov Data
    delete[] data;
    
    // alokovanie pola smernikov (pointer) na typ float
    (*data)[y].data2.fDataA = new float*[(*data)[y].data2.pocetDat2];
    // alokovanie  pola float-ov
    (*data)[y].data2.fDataA[i] = new float[pocetDat3];
    
    // dealokovanie 
    for(int y=;...;y++)
      for(int i;...;i++)
        delete  (*data)[y].data2.fDataA[i] ;
      delete (*data)[y].data2.fDataA;
    
    

    Založit nové vlákno • Nahoru

    Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

    ISSN 1214-1267   www.czech-server.cz
    © 1999-2015 Nitemedia s. r. o. Všechna práva vyhrazena.