Vector leeren



  • TR1 ist eben Technical Report 1. Das ist der wahrscheinlich-bald-Standard, aber solange nix abgesegnet ist, kann der noch geändert werden.



  • Oh. 😮

    Theoretisch könnten dann beim nächsten C++-Standard TR1-Bestandteile geändert werden und bisheriger Code, der TR1-Futures benutzt, könnte dann nicht mehr standardkonform sein?

    Ich dachte (das ist der Fehler! ;)), dass die TR1-Inhalte quasi feste Bestandteile des folgenden Standards sind. Nach dem Motto: "Das ist garantiert im nächsten Standard dabei!"



  • Roger Wilco schrieb:

    Ich dachte (das ist der Fehler! ;)), dass die TR1-Inhalte quasi feste Bestandteile des folgenden Standards sind. Nach dem Motto: "Das ist garantiert im nächsten Standard dabei!"

    Es ist nicht garantiert dabei, aber große Teile werden übernommen, ggf. mit leichte Modifikationen, die die neuen Möglichkeiten von C++0x berücksichtigen. Danach sind 4 verschiedene Dinge zu unterscheiden:

    - Die Spezifikationen im TR1
    - Die TR1-Implementierung durch die Compilerhersteller
    - Die Spezifikation im 0x-Standard
    - Die 0x-Implementierung durch die Compilerhersteller

    Alle zusammen müssen nicht identisch sein, sollten aber nur geringe Abweichungen voneinander haben.



  • vielen lieben Dank, dass ihr euch Zeit genommen und mir nicht nur eine Lösung gezeigt, sondern auch einiges erklärt habt.

    Wenn ich es also den Vector ohne new befülle, reicht es um die Member-Variable wieder zu leeren, in dem ich nur die Swap Methode aufrufe?

    Und nen Destruktor brauche ich dafür dann auch nicht mehr, da der komplette Speicher selbst freigegeben wird, wenn das Klassen-Objekt das diese Membervariable hat, zerstört wird.



  • Swap? theVector.clear() reicht.

    Edit: Wobei std::vector().swap(vec); auch interessant aussieht, aber welche Vorteile hat das?





  • swap() zum Leeren würde ich allerdings nur einsetzen, wenn es relevante Vorteile bringt. Es hat schon seine Gründe, warum clear() den Speicher nicht freigibt.



  • Würde nicht clear() gefolgt von resize(0) auch reichen? Als Grund stattdessen swapp/erase zu nutzen würde mir höchstens einfallen das andere STL Container kein resize() bieten und das somit für refaktoring günstiger wäre? Mhh vektor, list, deque bieten resize an, map, multimap und queue nicht - dafür habe map und multimap eigene swap Implementationen 😕

    Edith: Ok, swap with temporary reduziert den Speicher auf 0, clear/resize löscht alles, gibt aber keien reservierten Speicher frei 🙂



  • Würde nicht clear() gefolgt von resize(0)

    Nein. Das ist nicht dasselble wie swap with a temporary.



  • Resultat nachdem man mich mit der Nase reinstieß: swap mit temporary != clear();resize(); da letzteres keinen reservierten Speicher freigibt.

    class Elem
    {
        static int count_default;
        static int count_copy;
        static int count_opEqual;
        static int count_destruct;
    
    public:
        Elem()                           { ++count_default;  }
        Elem(const Elem & e)             { ++count_copy;     }
        Elem & operator=(const Elem & o) { ++count_opEqual;  return *this; }
        ~Elem()                          { ++count_destruct; }
    
        static void output()
        {
            std::cout << "DefaConst\tCopyConst\toperEqual\tDestructor\n" << count_default << "\t" << count_copy << "\t"<< count_opEqual << "\t"<< count_destruct << "\n\n\n" << std::endl;
            count_default=0;
            count_copy=0;
            count_opEqual=0;
            count_destruct=0;
        }
    };
    
    int Elem::count_default(0);
    int Elem::count_copy(0);
    int Elem::count_opEqual(0);
    int Elem::count_destruct(0);
    
    int main()
    {
        std::cout << "just out of scope:\n";
        {
            std::vector<Elem> es;
            // es.reserve(100); // 2. Ausgabe
            for (int i=0; i< 100; ++i) es.push_back(Elem());
        }
        Elem::output();
    
        std::cout << "clear and resize:\n";
        {
            std::vector<Elem> es;
            es.reserve(100);
            for (int i=0; i< 100; ++i) es.push_back(Elem());
    
            int cap_before = es.capacity();
            es.clear();
            es.resize(0);
            std::cout << "Capacity before/after: " << cap_before << "/" << es.capacity()<< std::endl;
        }
        Elem::output();
    
        std::cout << "swap with temoprary:\n";
        {
            std::vector<Elem> es;
            es.reserve(100);
            for (int i=0; i< 100; ++i) es.push_back(Elem());
    
            std::cout << es.capacity()<< std::endl;
            int cap_before = es.capacity();
            std::vector<Elem>().swap(es);
            std::cout << "Capacity before/after: " << cap_before << "/" << es.capacity()<< std::endl;
        }
        Elem::output();
    
    }
    
    CopyConst und Destructor: ohne/mit es.reserve(100);
    
    just out of scope:
    DefaConst    CopyConst    operEqual    Destructor
    100          227/100          0            327/200
    
    clear and resize:
    Capacity before/after: 100/100
    DefaConst    CopyConst    operEqual    Destructor
    101          227/100          0            328/201
    
    swap with temoprary:
    Capacity before/after: 100/0
    DefaConst    CopyConst    operEqual    Destructor
    100          227/100          0            327/200
    


  • padreigh schrieb:

    Würde nicht clear() gefolgt von resize(0) auch reichen?

    Das resize bringt da gar nichts. resize legt nur die Anzahl der Elemente fest, der reservierte Speicher wird aber nur verändert, wenn er vergößert werden muss.



  • ipsec schrieb:

    padreigh schrieb:

    Würde nicht clear() gefolgt von resize(0) auch reichen?

    Das resize bringt da gar nichts. resize legt nur die Anzahl der Elemente fest, der reservierte Speicher wird aber nur verändert, wenn er vergößert werden muss.

    Stimmt - ich habe die API wohl fehlinterpretiert:

    http://www.cplusplus.com/reference/stl/vector/resize/

    Change size
    Resizes the vector to contain sz elements. If sz is smaller than the current vector size, the content is reduced to its first sz elements, the rest being dropped.

    "the rest being dropped." beschränkt also nicht die Kapazität sondern nur den aktuellen Inhalt. Danke 🙂 wieder was gelernt.


Anmelden zum Antworten