Wer räumt eigentlich den Speicher auf ;-)



  • joomoo schrieb:

    Warum nicht boost? Da gibt's nähmlich boost::scoped_array und boost::shared_array. Und warum die nicht nehmen? So auf Geschwindigkeit ist dein programm sicher nicht aus oder?

    mfg.

    Weil man Boost auch wieder erst lernen muss. Ich frage mich ernsthaft, wann man in C++ anfangen kann, sich mit dem Programm zu beschäftigen anstatt mit der Sprache. Inwieweit ersetzt Boost denn die STL? Komplett oder ist das eher ergänzend? Ansonsten würde ich wohl eher auf Smartpointer und Boost verzichten und lieber solides Mittelalter lernen ...



  • xaoC schrieb:

    joomoo schrieb:

    Warum nicht boost? Da gibt's nähmlich boost::scoped_array und boost::shared_array. Und warum die nicht nehmen? So auf Geschwindigkeit ist dein programm sicher nicht aus oder?

    mfg.

    Weil man Boost auch wieder erst lernen muss. Ich frage mich ernsthaft, wann man in C++ anfangen kann, sich mit dem Programm zu beschäftigen anstatt mit der Sprache. Inwieweit ersetzt Boost denn die STL? Komplett oder ist das eher ergänzend? Ansonsten würde ich wohl eher auf Smartpointer und Boost verzichten und lieber solides Mittelalter lernen ...

    Du kannst dir ja nur die Sachen aus der boost rauspicken die du brauchst. Ist ja jetzt keine API. Die boost::shared_ptr Dinger sind echt total easy!

    mfg.



  • xaoC schrieb:

    Der Grund warum prinzipiell nicht per Value übergeben wird, ist doch der, sich anfallende Kosten für überflüssige Objekterstellung zu sparen

    Ja, aber auch nur, wenn das Objekt viel Daten enthält oder der ctor bzw. dtor nicht trivial ist.

    xaoC schrieb:

    Prinzipiell sei anzumerken, dass es überall gelehrt wird, per Referenz oder Zeiger zu übergeben, ob es von der Objektlebenszeit her sinnvoll ist oder nicht.

    Und wo soll sowas gelehrt werden? Bestimmt nicht von erfahrenen C++ Leuten. By-value zu übergeben, ist jedenfalls erstmal default. Nur wenn das zu teuer wird oder aufgrund von Polymorphie nicht möglich ist, übergibt man by-reference. Und bedenke, du übergibst in deinem Beispiel Zeiger. Also rein technisch gesehen by-value. 😉

    xaoC schrieb:

    Zielorientiert ist richtig, aber ich hätte trotzdem gerne deine Begründungen für Abweichungen von der meiner Meinung nach eher vorherrschenden Zeiger/Referenzübergabe gehört. Übergabe per Value sieht man nämlich fast nirgends, egal wie popelig das Beispiel.

    Ach ja? Wollen wir mal schnell den Standard durchgehen und jede Funktion anschauen, wo man fast nie by-value Übergabe sieht? Und auch ausserhalb des Standards wird das nicht viel anders aussehen. Keine Ahnung wovon du sprichst, aber mit der Realität hat das nicht viel zu tun, denn by-value verwendet man schon recht häufig.

    Zu deinem Problem:
    ich würde der Klasse ehrlich gesagt zwei normale string Objekte spendieren. Das wird wohl auch der gängiste Weg sein. Und über das Speichermanagement brauchst du dir dann auch keine Gedanken machen. Ansonsten, wenn du die Zeiger beibehalten willst, dann solltest du dir evtl. wirklich mal shared Pointer anschauen.
    Ach, und nochwas, std::string's dynamisch anzulegen ist so sinnvoll wie 'ne Badehose am Nordpol. Das ist praktisch doppelte Speicherreservierung und vollkommen unnötig. Somit ein weiteres Argument gegen deine bisherige Vorgehensweise und ebenfalls gegen eine Verwendung von Smart-Pointern an dieser Stelle, da man ja dann auf dynamisch erzeugte Objekte angewiesen ist. Insofern ist ein std::string Objekt ja schon dein "Array Smart-Pointer". Mir ist zwar immer noch nicht ganz klar, auf was du hinaus willst, aber evtl. suchst du ja sowas wie eine COW String Implementation.



  • xaoC schrieb:

    joomoo schrieb:

    Warum nicht boost? Da gibt's nähmlich boost::scoped_array und boost::shared_array. Und warum die nicht nehmen? So auf Geschwindigkeit ist dein programm sicher nicht aus oder?

    mfg.

    Weil man Boost auch wieder erst lernen muss. Ich frage mich ernsthaft, wann man in C++ anfangen kann, sich mit dem Programm zu beschäftigen anstatt mit der Sprache. Inwieweit ersetzt Boost denn die STL? Komplett oder ist das eher ergänzend? Ansonsten würde ich wohl eher auf Smartpointer und Boost verzichten und lieber solides Mittelalter lernen ...

    In der nächsten C++ Version sind die shared_ptr aus der Boost Teil der STL. Kann man sich im TR1 anschauen. (Tr steht für "Technical Report in Standart Library Extensions")

    Ansonsten kann ich für mich behaupten, dass ich keinen Speicher freigebe! Ich lasse den Speicher freigeben (von meinen Smart-Pointern). Damit bin ich sicher, dass ich keine Speicherleaks erzeuge. (von wenigen Ausnahmen abgesehen.)

    Noch ein Satz zu Feldern & Smart-Pointern: Die Smart-Pointer für Felder heißen std::vector und std::string.

    Sven



  • groovemaster schrieb:

    Ja, aber auch nur, wenn das Objekt viel Daten enthält oder der ctor bzw. dtor nicht trivial ist.

    Das ist einleuchtend und bedarf wohl auch keiner Diskussion.

    groovemaster schrieb:

    Und wo soll sowas gelehrt werden? Bestimmt nicht von erfahrenen C++ Leuten.

    Ich will jetzt nicht nachschlagen, aber ich schätze in ca. 80% der Lehrbücher.
    Schulen lehren es übrigens genauso. Jedenfalls ist der Eindruck der entsteht, ganz klar: "Nutzt Zeiger/Referenzen etc., ist besser, schneller etc.".

    groovemaster schrieb:

    By-value zu übergeben, ist jedenfalls erstmal default. Nur wenn das zu teuer wird oder aufgrund von Polymorphie nicht möglich ist, übergibt man by-reference. Und bedenke, du übergibst in deinem Beispiel Zeiger. Also rein technisch gesehen by-value. 😉

    By-Value ist Default, ja, da weiß ich auch.
    Mit geht's auch nicht darum, Zeigerübergabe als Standard zu propagieren oder für irgendetwas Werbung zu machen, sondern herauszufinden, wie eure
    Vorgehensweise da aussieht.

    groovemaster schrieb:

    Ach ja? Wollen wir mal schnell den Standard durchgehen und jede Funktion anschauen, wo man fast nie by-value Übergabe sieht?

    Nein, will ich nicht. Weil es nicht das ist, was ich bis jetzt gesehen habe. Grundtypen wie int oder float als Parameter by value zu übergeben ist gängig, bei Objekten sieht das IMO ganz anders aus.
    Mit stellte sich die Sinnfrage nach solchen Konstrukten wie ich im ersten Post angegeben habe. Und die Übergabe per value scheint hier nur logisch. Aber da muss man doch mal drüber reden können.

    groovemaster schrieb:

    Und auch ausserhalb des Standards wird das nicht viel anders aussehen. Keine Ahnung wovon du sprichst, aber mit der Realität hat das nicht viel zu tun, denn by-value verwendet man schon recht häufig.

    s.o.

    groovemaster schrieb:

    Zu deinem Problem:
    ich würde der Klasse ehrlich gesagt zwei normale string Objekte spendieren. Das wird wohl auch der gängiste Weg sein. Und über das Speichermanagement brauchst du dir dann auch keine Gedanken machen.

    Ack.

    groovemaster schrieb:

    Ansonsten, wenn du die Zeiger beibehalten willst, dann solltest du dir evtl. wirklich mal shared Pointer anschauen.

    kk.

    groovemaster schrieb:

    Ach, und nochwas, std::string's dynamisch anzulegen ist so sinnvoll wie 'ne Badehose am Nordpol. Das ist praktisch doppelte Speicherreservierung und vollkommen unnötig.

    Für mich ist ein std::string erst mal ein Objekt wie jedes andere auch. Wenn ich dieses auf dem Heap anlegen will mache ich ein new. Ich weiss nicht was
    da jetzt doppelt reserviert werden soll?

    groovemaster schrieb:

    Mir ist zwar immer noch nicht ganz klar, auf was du hinaus willst, [...].

    Es geht mir im Grunde darum, inwieweit Übergaben NICHT als value in solchen Fällen wie oben Sinn machen, wenn nicht, warum und was Alternativen dazu wären.

    Das Fazit, was ich aus dieser Diskussion hier mitnehme, ist im Prinzip:
    - Nutze SmartPointer wenn möglich
    - by value in diesem Falle sinnvoll

    Was definitiv so in meiner Gegenwart im Grunde nirgends vermittelt wurde (allgemein gemünzt):
    Mehr die Vorgehensweise als die Technik zu beachten. Denn no-by value ist IMO für komplexere Objekte als Grundtypen eher Standard in Literatur als by value. Meine Meinung. Das das keinen Sinn macht, wenn man den Kontext nicht betrachtet, ist mir dann auch klar, aber wie IHR den Kontext seht, hat mich interessiert.



  • Für mich ist ein std::string erst mal ein Objekt wie jedes andere auch. Wenn ich dieses auf dem Heap anlegen will mache ich ein new. Ich weiss nicht was
    da jetzt doppelt reserviert werden soll?

    Die Frage lautet: WOZU willst du es auf dem Heap anlegen? Das würde nur bei C-Strings einen Sinn ergeben. Und Falls du mehrere String-Objekte brauchst dann nimm std::vector und nicht new[].

    mfg.



  • sven_jo schrieb:

    Noch ein Satz zu Feldern & Smart-Pointern: Die Smart-Pointer für Felder heißen std::vector und std::string.
    Sven

    Das sind keine SmartPtr sonder ein dynamisches Array und ein String, die verwalten zwar intern auch den benötigten Speicher aber SmartPtr sind etwas anderes.



  • xaoC @ Work schrieb:

    Ich will jetzt nicht nachschlagen, aber ich schätze in ca. 80% der Lehrbücher.
    Schulen lehren es übrigens genauso. Jedenfalls ist der Eindruck der entsteht, ganz klar: "Nutzt Zeiger/Referenzen etc., ist besser, schneller etc.".

    Ok, ist schon etwas länger her, dass ich ein C++ Lehrbuch in den Händen hatte. Aber ich hoffe, du hast das nicht falsch verstanden. By-reference darf nicht Ziel der Parameterübergabe sein, es ist einfach ein zweckgebundenes sprachunabhängiges Mittel.

    xaoC @ Work schrieb:

    Für mich ist ein std::string erst mal ein Objekt wie jedes andere auch. Wenn ich dieses auf dem Heap anlegen will mache ich ein new. Ich weiss nicht was
    da jetzt doppelt reserviert werden soll?

    Du bemühst den Speichermanager, die paar Bytes die std::string für seine Member benötigt, zu reservieren. Intern bemüht std::string wieder den Speichermanager (bzw. verwendeten Allokator), um Speicher für den Inhalt der Zeichenkette zu reservieren. Das ist ungefähr so absurd, wie einen Smart-Pointer dynamisch zu reservieren (ok, leicht übertrieben). Aber um das mal mit dem Thema zu verbinden, die sinnvolle Verwendung von automatischem und dynamischem Speicher erfordert letztendlich genauso viel Fingerspitzengefühl, wie die Parameterübergabe by-value oder by-reference.

    xaoC @ Work schrieb:

    - Nutze SmartPointer wenn möglich

    Smart-Pointer aber nur, wenn man keinen passenden Container parat hat und einem der evtl. Overhead egal ist. Ich würde es deshalb eher wie folgt formulieren:

    Nutze Smart-Pointer wenn möglich anstatt roher Zeiger.

    xaoC @ Work schrieb:

    Mehr die Vorgehensweise als die Technik zu beachten. Denn no-by value ist IMO für komplexere Objekte als Grundtypen eher Standard in Literatur als by value.

    Was ja auch vollkommen ok ist. Nur man sollte halt nicht stur eine Vorgehensweise durchziehen, sondern die gebotenen Sprachmittel diesbzgl. sinnvoll einsetzen.



  • xaoC schrieb:

    Weil man Boost auch wieder erst lernen muss. Ich frage mich ernsthaft, wann man in C++ anfangen kann, sich mit dem Programm zu beschäftigen anstatt mit der Sprache.

    Boost gehört nicht zur Sprache, genauso wie die STL im eigentlichen Sinne. Sie gehört zwar zum Standard, ist aber nicht fest integriert sondern eben eine Bibliothek, ergo beschäftigst du dich nicht mit der Sprache, wenn du dich mit der STL beschäftigst. (Sie wurde auch zu erst nicht in C++ sondern in Ada implementiert!)

    xaoC schrieb:

    Inwieweit ersetzt Boost denn die STL? Komplett oder ist das eher ergänzend?

    Sie ergänzt und erweitert/verbessert in einigen Bereichen (z.B. Iteratoren)

    Zur laufenden Diskussion:
    Kommt es nicht auch ein wenig darauf an, wie man by-(value|reference) definiert? Aus implementierungsunabhängiger Sicht ist doch eine const Referenz eigentlich auch eine by-value Übergabe (schließlich wird der übergebene Wert nicht verändert). Auch die Regel für die Übergabe von Objekten kann man sprachunabhängig auf die Fälle "Verändern" und "Nicht verändern" bringen, für beide gibt es je nach Parametertyp klare Vorgehensweisen.
    Außerdem möchte ich noch anmerken, dass Zeiger als Parameter selten sinnvoll sind, zumindest wenn es sich um eine normale Objektübergabe handelt. Schließlich benutzt man Zeiger in C++ nur, wenn es sich um veränderlichen (Adressbezogen) oder auf dem Heap zu alloziierenden Speicher handelt, ansonsten reichen Referenzen. Auch für Smartpointer fiele mir jetzt kein sinnvolles Szenario ein.
    Also, wo ist das Problem?



  • Konrad schrieb:

    sven_jo schrieb:

    Noch ein Satz zu Feldern & Smart-Pointern: Die Smart-Pointer für Felder heißen std::vector und std::string.
    Sven

    Das sind keine SmartPtr sonder ein dynamisches Array und ein String, die verwalten zwar intern auch den benötigten Speicher aber SmartPtr sind etwas anderes.

    Vollkommen korrekt! Da C++ Klassen für dynamische Arrays und Strings besitzt, braucht man keine Smart-Ptr für Felder. Daher meine Aussage: Die Smart-Pointer für Felder heißen std::vector und std::string.

    Die Smart-Pointer boost::scoped_array und boost::shared_array könnten zum migrieren von altem Code verwendet werden. Diese Vorgehensweise kann ich nicht empfehlen.

    Wenn man in seinem Code ein new[...] / delete ...[] verwendet, sollte man den Code auf echte C++-Klassen für dynamische Felder oder Strings umstellen. -> also: std::vector und std::string.

    Sven



  • sven_jo schrieb:

    Konrad schrieb:

    sven_jo schrieb:

    Noch ein Satz zu Feldern & Smart-Pointern: Die Smart-Pointer für Felder heißen std::vector und std::string.
    Sven

    Das sind keine SmartPtr sonder ein dynamisches Array und ein String, die verwalten zwar intern auch den benötigten Speicher aber SmartPtr sind etwas anderes.

    Vollkommen korrekt! Da C++ Klassen für dynamische Arrays und Strings besitzt, braucht man keine Smart-Ptr für Felder. Daher meine Aussage: Die Smart-Pointer für Felder heißen std::vector und std::string.

    so ein quatsch. strings stellen zeichenketten dar und vector stellet dynamische arrays dar.

    außerdem: vector und string sind im allgemeinen gute sachen und smartpointers sind im allgemeinen schlechte sachen.


  • Mod

    volkard schrieb:

    sven_jo schrieb:

    Konrad schrieb:

    sven_jo schrieb:

    Noch ein Satz zu Feldern & Smart-Pointern: Die Smart-Pointer für Felder heißen std::vector und std::string.
    Sven

    Das sind keine SmartPtr sonder ein dynamisches Array und ein String, die verwalten zwar intern auch den benötigten Speicher aber SmartPtr sind etwas anderes.

    Vollkommen korrekt! Da C++ Klassen für dynamische Arrays und Strings besitzt, braucht man keine Smart-Ptr für Felder. Daher meine Aussage: Die Smart-Pointer für Felder heißen std::vector und std::string.

    so ein quatsch. strings stellen zeichenketten dar und vector stellet dynamische arrays dar.

    außerdem: vector und string sind im allgemeinen gute sachen und smartpointers sind im allgemeinen schlechte sachen.

    das von jemand, für den alle verallgemeinerungen falsch sind?

    smartpointer sind ein mittel wie jedes andere, um probleme zu lösen - sie können nützlich sein; aber sie um der verwendung willen einzusetzen wird eher problem verursachen. das "schlechte" daran ist dann aber immer noch nicht der smartpointer, sondern der programmierer, der ihn benutzt.



  • volkard schrieb:

    sven_jo schrieb:

    Konrad schrieb:

    sven_jo schrieb:

    Noch ein Satz zu Feldern & Smart-Pointern: Die Smart-Pointer für Felder heißen std::vector und std::string.
    Sven

    Das sind keine SmartPtr sonder ein dynamisches Array und ein String, die verwalten zwar intern auch den benötigten Speicher aber SmartPtr sind etwas anderes.

    Vollkommen korrekt! Da C++ Klassen für dynamische Arrays und Strings besitzt, braucht man keine Smart-Ptr für Felder. Daher meine Aussage: Die Smart-Pointer für Felder heißen std::vector und std::string.

    so ein quatsch. strings stellen zeichenketten dar und vector stellet dynamische arrays dar.

    außerdem: vector und string sind im allgemeinen gute sachen und smartpointers sind im allgemeinen schlechte sachen.

    du schuldest uns aber immernoch eine aufschlüsselung darüber, wieso 😉



  • otze schrieb:

    du schuldest uns aber immernoch eine aufschlüsselung darüber, wieso 😉

    smartpoiunter tauchen meistens dann auf, wenn man designfehler wegfrickeln muß. mehr dazu im letzten thread über smartpointer.



  • Ein Container polymorpher Objekte ist ein Designfehler? Also bitte ...



  • volkard würde einen Wrapper um den Container schreiben der im Destruktor für jedes Element delete aufruft.



  • ao schrieb:

    volkard würde einen Wrapper um den Container schreiben der im Destruktor für jedes Element delete aufruft.

    vielleicht würde er auch einen container mit lösch-policy haben. alexandrescu er gelesen hat.



  • 🙂


  • Mod

    volkard schrieb:

    ao schrieb:

    volkard würde einen Wrapper um den Container schreiben der im Destruktor für jedes Element delete aufruft.

    vielleicht würde er auch einen container mit lösch-policy haben. alexandrescu er gelesen hat.

    alexandrescu smart pointer mag. ihnen einen großen teil von MCPPD eingeräumt hat.



  • Bitte deutsch, wir sind hier nicht im Kindergartenforum.


Anmelden zum Antworten