map am ende löschen?



  • damm schrieb:

    Wenn du dich nicht um die Zerstörung der Objekte kümmern willst, benutzte referenzzählende Smart-Pointer. Gibt es auf www.boost.org

    ich denke, solche geschütze sollte man erst auffahren, wenn man dazu gezwungen wird. also insbesondere, wenn man gar nicht verfolgen kann, wer der besitzer des objektes ist.
    meistens ist aber eh die map der alleinige besitzer und dann kann man das auch per hand machen.



  • ok danke, muss ich aber trotzdem am ende die map leeren?



  • c++anfänger04 schrieb:

    ok danke, muss ich aber trotzdem am ende die map leeren?

    ja.



  • c++anfänger04 schrieb:

    ok danke, muss ich aber trotzdem am ende die map leeren?

    Du meinst, ob du hinterher

    mymap.clear();
    

    aufrufen musst? Nein, das macht die map selber.



  • volkard schrieb:

    damm schrieb:

    Wenn du dich nicht um die Zerstörung der Objekte kümmern willst, benutzte referenzzählende Smart-Pointer. Gibt es auf www.boost.org

    ich denke, solche geschütze sollte man erst auffahren, wenn man dazu gezwungen wird. also insbesondere, wenn man gar nicht verfolgen kann, wer der besitzer des objektes ist.
    meistens ist aber eh die map der alleinige besitzer und dann kann man das auch per hand machen.

    Erklär mal.
    Warum sollte ich es mir nicht einfach machen?



  • __me schrieb:

    Erklär mal.
    Warum sollte ich es mir nicht einfach machen?

    wegen performance. du haust einfach mal so ro zeiger noch 4 bytes für den refcounter dazu. dabei reichen 0 bytes vollkommen aus. ist sich kleiner und schneller (weil gar nix immer und immer wieder auf 0 getestet werden muss.)
    aber die frage von dir war nicht dein ernst. du kannst nur ein troll sein.



  • volkard schrieb:

    __me schrieb:

    Erklär mal.
    Warum sollte ich es mir nicht einfach machen?

    wegen performance. du haust einfach mal so ro zeiger noch 4 bytes für den refcounter dazu. dabei reichen 0 bytes vollkommen aus. ist sich kleiner und schneller (weil gar nix immer und immer wieder auf 0 getestet werden muss.)
    aber die frage von dir war nicht dein ernst. du kannst nur ein troll sein.

    A) Scheiß auf Performance. Wen interessiert sowas?
    😎 Würde ich mich um Performance kümmern würde ich nicht auf std::map setzen, sondern auf einen Hash.
    C) Wieso sollte ein Anfänger eine solche Frage nicht stellen dürfen? Ich finde das absolut nicht trollig.



  • Helium schrieb:

    A) Scheiß auf Performance. Wen interessiert sowas?

    C++ ist eine Sprache, die aufgrund der Performance auf einige Annehmlichkeiten wie z.B. Garbage Collection und weitgehend definiertes Verhalten verzichtet. Warum sollte man sich das antun, wenn man nicht wenigstens sekundär auf Performance aus ist? Es gibt so viele andere schöne Programmiersprachen ...



  • Helium schrieb:

    A) Scheiß auf Performance. Wen interessiert sowas?

    hier würde ich normalerweise sagen: geh und spiel mit java. aber bashars worte klingen viel besser.

    😎 Würde ich mich um Performance kümmern würde ich nicht auf std::map setzen, sondern auf einen Hash.

    sicher? immer? also ich kenne fälle, wo die map schneller als die hashtable ist.
    aber darm gehts nicht. es ist einfach sehr wahrscheinlich, daß die map member eines grölßeren objekts ist und dem größeren objekt in den dtor zu schreiben, daß die map auch noch ihre zeiger löschen soll, ist doch nullinger aufwand. es ist direkt und fein. das nächstfeinere ist, der map als policy mitzugeben, was mit sachen passieren soll, die vom map-dtor betroffen wären. allein die refcounting pointers sind einfach nicht naheliegend, nicht elegant, und nicht performant. wozu also?

    C) Wieso sollte ein Anfänger eine solche Frage nicht stellen dürfen? Ich finde das absolut nicht trollig.

    es war __me, der sich da unregistriert in nen laufenden thread getan hat. nicht c++anfaenger04. und fragen darf jeder alles. kann halt sein, daß ich manchmal widerspreche, metaaussagen trefe, den beitrag oder den thread lösche oder verschiebe.



  • sicher? immer? also ich kenne fälle, wo die map schneller als die hashtable ist.

    Jetzt bin ich gespannt.
    Man kann doch problemlos Hashs bauen, die bei mehrfachen berechnen der selben stelle eine Liste verwenden und dort sortiert einfügen. Somit kann man beim Suchen einen logarythmischen Worst Case erziehlen.
    Darum kann es also schonmal nciht gehen. Zeig bzw. erklär mal wo deine Map schneller ist.



  • Helium schrieb:

    sicher? immer? also ich kenne fälle, wo die map schneller als die hashtable ist.

    Jetzt bin ich gespannt.
    Man kann doch problemlos Hashs bauen, die bei mehrfachen berechnen der selben stelle eine Liste verwenden und dort sortiert einfügen. Somit kann man beim Suchen einen logarythmischen Worst Case erziehlen.
    Darum kann es also schonmal nciht gehen. Zeig bzw. erklär mal wo deine Map schneller ist.

    na, das hashen selbst kostet doch.
    nehmen wir als hashfunktion mal

    unsigned int hash::hashstr(String &x)
    {
    	return hashstr(x.c_str());
    }
    
    unsigned int hash::hashstr(const char* x)
    {
      unsigned int h = 0;
      unsigned int g;
    
      while (*x != 0)
      {
        h = (h << 4) + *x++;
        if ((g = h & 0xf0000000) != 0)
          h = (h ^ (g >> 24)) ^ g;
      }
      return h;
    }
    

    und die wahl ist nicht sehr unwahrscheinlich.
    und leider habe ich lauter sehr, sehr, sehr lange strings zu verwalten. sagen wir mal in ner BWT. und beim vergleich mit strcpy fliegt gewöhnlich nach dem ersten zeichen schon ein ergebnis. mit geriner wahrscheinlichkeit muß man auch das zweite angucken, und mit saugeriger wahrscheinlichkeit sogar noch das dritte...
    da kann es locker mal sein, daß ein paar stringvergleiche (für ne million srtings nur 20 strück) für den baum billiger sind, als nen megabytestring durchzuhashen.



  • ok, verstanden. Danke.



  • habs ebenfalls verstanden, danke 👍



  • volkard schrieb:

    wegen performance. du haust einfach mal so ro zeiger noch 4 bytes für den refcounter dazu. dabei reichen 0 bytes vollkommen aus. ist sich kleiner und schneller (weil gar nix immer und immer wieder auf 0 getestet werden muss.)

    Und du hast noch gar nicht auf die zusätzliche Allokation hingewiesen, die shared_ptr AFAIK immer noch macht. Aber nur weil man in C++ an den entscheidenden Stellen schnell sein kann, schadet der Luxus von shared_ptrs in anderen Teilen des Programms doch nicht... 😕 Ich oute mich jedenfalls als so Boost-süchtig, dass mir die shared_ptr-Lösung gedanklich auch einfacher zu verarbeiten vorkommt als die, wo ich an deletes denken muss.



  • Frage: Es geht doch um Performance. Wenn mir auffällt, dass sich die langen Texte in der Regel bereits durch die ersten paar Zeichen unterscheiden, warum baue ich mir keinen Hasher, der nur eben diese Zeichen beachtet? Da ich bei einem Baum doch einige Vergleiche benötige werde ich den Baum IMO schnell wieder überholen.

    Gut, ich hatte noch nie lange Texte als Index und habe mir deswegen tatsächlich noch nie Gedanken darüber gemacht.



  • Helium schrieb:

    Frage: Es geht doch um Performance. Wenn mir auffällt, dass sich die langen Texte in der Regel bereits durch die ersten paar Zeichen unterscheiden, warum baue ich mir keinen Hasher, der nur eben diese Zeichen beachtet?

    solange man nicht auf die idee kommt, sich auf die ersten 8 zeichen zu beschränken und hinter der hashtable nur ne verkettete liste zu haben, gehts. deine idee mit bäumen hinter der table macht vieles möglich.

    Da ich bei einem Baum doch einige Vergleiche benötige werde ich den Baum IMO schnell wieder überholen.

    jo. sagen wie mal, man beachtet nur das erste zeichen!
    statt

    map<string,Foo> dictionary;
    

    und

    void insert(string key,Foo value){
       dictionary[key]=value;
    }
    

    schreibt man einfach

    map<string,Foo> dictionary[256];
    

    und

    void insert(string key,Foo value){
       dictionary[u8(key[0])][key]=value;
    }
    

    spart mit einem tabellengucker (mal gleichverteilng der schlüssel angenommen) gleich 8 verzweigungen. die tabelle kann natürlich auch größer sein, also zwei buchstaben angucken. oder sogar mehrere (wenige) buchstaben angucken und hashen.
    ich setze gerne mit so einfachen tabellenguckern zuvor die suchtiefe runter. das erlaubt dann oft sogar, mal unewöhliche strukturen wie move-to-front-lists zu nehmen oder was ich auch sehr mag, sind hashtables, die fixed sized sind und im falle der kollisiion einfach den alten wert überschreiben. also caches. die kann man fein vor teure rechnungen hängen.



  • operator void schrieb:

    Aber nur weil man in C++ an den entscheidenden Stellen schnell sein kann, schadet der Luxus von shared_ptrs in anderen Teilen des Programms doch nicht... 😕 Ich oute mich jedenfalls als so Boost-süchtig, dass mir die shared_ptr-Lösung gedanklich auch einfacher zu verarbeiten vorkommt als die, wo ich an deletes denken muss.

    haste dir schonmal gedanken gemacht, wie du die kraft von c++ noch viel voller ausschöpfen kannst? indem du java benutzt.
    dort gibt es nen geilen garbage collector und schnell ist die sace auch. und du brauchst vor zeiger kein sternchen mehr zu malen. es gibt auch templates und sicher ist es und überhaupt.
    welchen sinn hat es, sich eingehend mit c++ zu beschäftigen? sauberer java-code, und man sagte mir, es gäbe ihn, ist auch recht schnell. das wäre doch besser, als in c++ hie und da mit shared_ptr rumzumachen und dann vergißt man es doch wanders und alles schmiert wiedermal ab.

    in c++ muß man nicht umständlich ans delete denken. in c++ denkt man IMMER ans delete. ganz einfach ist das. zu jedem new gehöer ein delete. immer. immer. immer. wenn du das aufweichst mit der verwendung von shared_ptr an den nutzlosesten stellen, dann wirste nie mehr klar im kopp, wo du vielleicht doch mal eins brauchst und dein c++-code wird genauso unsicher, wie anno dazumal der c-code war. siehe absturzanzahl von win311 und zugehörigen applikationen. du mußt dich entscheiden: entweder mach den schritt ganz und geh zu java oder bleib hier aber versaue die nichts.

    zu viele designentscheidungen von c++ ehen deutlich nicht in richtung letzem komfort, um dann so zu tun, als sei es doch so. das wird inkonsistent und grausam. benutze c++ für die probleme, wo die ein wenig öl an den fingern nicht weh tut. benutze c++, wenn du peak performance suchst, aber auch was dafür zahlen magst. ich löse die hälfte meiner (programmier-)probleme in perl, vb und php. insbesondere vb nimmt bei mir an bedeutung zu und wird evtl demnächst von c# abgelöst.

    bald isses soweit, daß boost-sucht als krankheit eingestuft werden muß. ich sehe immer mehr boost-mißbrauch. und jedesmal ohne das geringste schlechte gewissen beim kranken.



  • Wie kriegt man eigentlich ein erase bei nem Container mit um sein delete aufzurufen?

    Wenn man einen Container hat der Zeiger aufnimmt, ihn am Anfang füllt und am Ende wieder alles freigibt - kein Problem. Aber was ist, wenn man irgendwann einen Zeiger mit erase auf dem Container entfernt? Dann kann der doch nicht mehr freigegeben werden, oder?!



  • Dann machs vorher.



  • Helium schrieb:

    Dann machs vorher.

    genau.
    und der container hat doch eh nen wrapper drum, um anwendungsnamen wie Personalliste auf std-namen wie str::map<int,Person*> zu mappen.
    der kann das fein machen.

    void Personal::toeten(int id){
       delete leute[id];
       leute.erase(id);
    }
    

Anmelden zum Antworten