Uživatelské nástroje

Nástroje pro tento web


cpp_tips

Toto je starší verze dokumentu!


Tipy & triky C++

char* do istringstrem

  • jak z velkého pole znaků udělat istringstream bez kopírování v paměti?
  • následující kód paměť kopíruje až 3x (záleží na implementaci copy on write)
char *mybuf[] = "very very .. long";
istringstream myss(string(mybuf, strlen(mybuf)));  
  • finta
char *mybuf[] = "very very .. long";
istringstream dfile;
dfile.rdbuf()->pubsetbuf(mybuf, strlen(mybuf));
  • ověřil jsem to zavoláním free na mybuff (kód se musí upravit na dynamickou alokaci mybuf)

Default parametry metody/funkce

  • mám metodu s více parametry. Někdy mi ale stačí změnit jen ten první a ostatní jako default
  • jako default lze dokonce použít i funkci nebo proměnou
// declaration
void setSomething(int val1 = 1, int val2 = 2, int val3 = 3);
 
// definition
void setSomething(int val1, int val2, int val) {
  this.val1 = val1;
  this.val2 = val2;
  this.val3 = val3;  
}
 
// calling
setSomething(1);
setSomething(1,2);
setSomething(1,2,3);

Zákeřné dočasné objekty

  • dočasné objekty mají životnost pouze v rámci výrazu
  • příklad se stringstream: chceme postupně vyčítat všechny znaky stringu
  • první varianta
    • v každé iteraci se provádí znovu alokace paměti pro dočasný objekt str včetně kopírování obsahu
    • nejspíš dokonce dvojnásobně, ještě pro volání size
    • valgrind naměřil (celý program): total heap usage: 9,890 allocs, 9,868 frees, 1,207,634 bytes allocated
    int i;
    for (i=0; i<outstr.str().size(); ++i) {
        hash = ((hash << 5) + hash) + outstr.str()[i]; // hash * 33 + c
    }
  • druhá varianta
    • vůbec nefunguje - nekončeně cyklí kvůli memory leaku
    for (string::const_iterator it = outstr.str().begin(); it != outstr.str().end(); ++it) {
        hash = ((hash << 5) + hash) + *it; // hash * 33 + c
    }
  • třetí varianta
    • správné řešení
    • teoreticky se ale kopíruje paměť str objektu do mystr
    • valgrind naměřil (celý program): total heap usage: 9,148 allocs, 9,126 frees, 913,802 bytes allocated
    string mystr(outstr.str());
    for (string::const_iterator it = mystr.begin(); it != mystr.end(); ++it) {
        hash = ((hash << 5) + hash) + *it; // hash * 33 + c
    }
  • čtvrtá varianta
    • mělo by být nejvíce šetrné k paměti
    • objekt str by se neměl kopírovat, měla by se pouze prodloužit jeho životnost
    • hrozí zde stále nebezpečí přepsání obsahu.. ukazatel ukazuje na interní buffer, který se může při práci se stringstream měnit
    • valgrind naměřil překvapivě stejný počet alokací, jako v předchozím případě. Nejspíš zabrala nějaká optimalizace při kompilaci
    const string& mystr = outstr.str();
    for (string::const_iterator it = mystr.begin(); it != mystr.end(); ++it) {
        hash = ((hash << 5) + hash) + *it; // hash * 33 + c
    }

struct na/z string

cpp_tips.1461595682.txt.gz · Poslední úprava: (upraveno mimo DokuWiki)

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki