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í
×
eParkomat, startup z ČR, postoupil mezi finalisty evropského akcelerátoru ChallengeUp!
Robot na pivo mu otevřel dveře k opravdovému byznysu
Internet věcí: Propojený svět? Už se to blíží...
dnes 12:00 | Zajímavý projekt

Projekt Termbox umožňuje vyzkoušet si linuxové distribuce Ubuntu, Debian, Fedora, CentOS a Arch Linux ve webovém prohlížeči. Řešení je postaveno na projektu HyperContainer. Podrobnosti v často kladených dotazech (FAQ). Zdrojové kódy jsou k dispozici na GitHubu [reddit].

Ladislav Hagara | Komentářů: 7
dnes 11:00 | Bezpečnostní upozornění

Byly zveřejněny informace o bezpečnostní chybě CVE-2016-8655 v Linuxu zneužitelné k lokální eskalaci práv. Chyba se dostala do linuxového jádra v srpnu 2011. V upstreamu byla opravena minulý týden [Hacker News].

Ladislav Hagara | Komentářů: 0
včera 22:00 | Komunita

Přibližně před měsícem bylo oznámeno, že linuxová distribuce SUSE Linux Enterprise Server (SLES) běží nově také Raspberry Pi 3 (dokumentace). Obraz verze 12 SP2 pro Raspberry Pi 3 je ke stažení zdarma. Pro registrované jsou po dobu jednoho roku zdarma také aktualizace. Dnes bylo oznámeno, že pro Raspberry Pi 3 je k dispozici také nové openSUSE Leap 42.2 (zprávička). K dispozici je hned několik obrazů.

Ladislav Hagara | Komentářů: 5
včera 06:00 | Zajímavý software

OMG! Ubuntu! představuje emulátor terminálu Hyper (GitHub) postavený na webových technologiích (HTML, CSS a JavaScript). V diskusi k článku je zmíněn podobný emulátor terminálu Black Screen. Hyper i Black Screen používají framework Electron, stejně jako editor Atom nebo vývojové prostředí Visual Studio Code.

Ladislav Hagara | Komentářů: 39
včera 06:00 | Zajímavý článek

I letos vychází řada ajťáckých adventních kalendářů. QEMU Advent Calendar 2016 přináší každý den nový obraz disku pro QEMU. Programátoři se mohou potrápit při řešení úloh z kalendáře Advent of Code 2016. Kalendáře Perl Advent Calendar 2016 a Perl 6 Advent Calendar přinášejí každý den zajímavé informace o programovacím jazyce Perl. Stranou nezůstává ani programovací jazyk Go.

Ladislav Hagara | Komentářů: 9
3.12. 16:24 | Nová verze

Byla vydána Mageia 5.1. Jedná se o první opravné vydání verze 5, jež vyšla v červnu loňského roku (zprávička). Uživatelům verze 5 nepřináší opravné vydání nic nového, samozřejmě pokud pravidelně aktualizují. Vydání obsahuje všechny aktualizace za posledního téměř půldruhého roku. Mageia 5.1 obsahuje LibreOffice 4.4.7, Linux 4.4.32, KDE4 4.14.5 nebo GNOME 3.14.3.

Ladislav Hagara | Komentářů: 17
3.12. 13:42 | Pozvánky

V Praze probíhá konference Internet a Technologie 16.2, volné pokračování jarní konference sdružení CZ.NIC. Konferenci lze sledovat online na YouTube. K dispozici je také archiv předchozích konferencí.

Ladislav Hagara | Komentářů: 0
2.12. 22:44 | Komunita

Joinup informuje, že Mnichov používá open source groupware Kolab. V srpnu byl dokončen dvouletý přechod na toto řešení. V provozu je asi 60 000 poštovních schránek. Nejenom Kolabu se věnoval Georg Greve ve své přednášce Open Source: the future for the European institutions (SlideShare) na konferenci DIGITEC 2016, jež proběhla v úterý 29. listopadu v Bruselu. Videozáznam přednášek z hlavního sálu je ke zhlédnutí na Livestreamu.

Ladislav Hagara | Komentářů: 25
2.12. 15:30 | Zajímavý projekt

Společnost Jolla oznámila v příspěvku Case study: Sailfish Watch na svém blogu, že naportovala Sailfish OS na chytré hodinky. Využila a inspirovala se otevřeným operačním systémem pro chytré hodinky AsteroidOS. Použita je knihovna libhybris. Ukázka ovládání hodinek na YouTube.

Ladislav Hagara | Komentářů: 18
2.12. 14:15 | Nová verze

Byla vydána verze 7.1.0 skriptovacího jazyka PHP používaného zejména k vývoji dynamických webových stránek. Jedná se o první stabilní verzi nejnovější větvě 7.1. Přehled novinek v dokumentaci. Podrobnosti v ChangeLogu. K dispozici je také příručka pro přechod z PHP 7.0.x na PHP 7.1.x.

Ladislav Hagara | Komentářů: 6
Kolik máte dat ve svém domovském adresáři na svém primárním osobním počítači?
 (32%)
 (24%)
 (29%)
 (7%)
 (5%)
 (3%)
Celkem 775 hlasů
 Komentářů: 50, poslední 29.11. 15:50
Rozcestník
Reklama

Dotaz: Dynamicky alokované pole struktur

Beda0 avatar 11.5.2013 15:49 Beda0 | skóre: 28
Dynamicky alokované pole struktur
Přečteno: 967×
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: 66
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: 28
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: 28
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: 28
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: 28
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: 28
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: 28
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: 28
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: 28
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: 28
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: 28
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: 28
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: 66
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: 28
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: 66
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áknoNahoru

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.