Dynamische Array Container Implementierung



  • camper schrieb:

    SeppJ schrieb:

    camper schrieb:

    SeppJ schrieb:

    camper schrieb:

    ~DynArray(){
            if ( pfirst != 0 )  // optional
                delete [] pfirst;
        }
    

    Optional? Du meinst wohl "vollkommen wirkungslos und verwirrend".

    Jetzt bin ich verwirrt :p

    Na, wenn pfirst == 0 wäre, dann würde delete[] pfirst; genau gar nix machen (vom Standard garantiert). Dafür verwirrst du nun Broly, der vielleicht denkt, dass diese Abfrage auch nur irgendwie nützlich wäre.

    Genau gar nix ist auch recht unpräzise (der Standard an dieser Stelle allerdings auch). Die Diskussion über das Für und Wider einer solchen Abfrage wurde an anderer Stelle bereits geführt, das möchte ich nicht aufwärmen.
    Es gibt im Grunde zwei Argumente, die für eine solche Abfrage sprechen:
    1. Symmetrie: zu jeder Deallokation gehört eine erfolgreiche Allokation (das ist das einzige Argument, das für mich persönlich relevant ist - Programme sollten lesbar bein)

    Als würde new einen Nullzeiger zurückgeben, wenn es fehlschlägt.. Was meinst du also mit Symmetrie?

    camper schrieb:

    2. "Genau nix" ist immer noch ein Funktionsaufruf mehr als nötig

    Mikrooptimierungen rechtfertigen natürlich jeden Mist.
    Woher weißt du, ob nicht viel mehr Folgendes zutrifft: In den meisten Fällen ist der Zeiger ungleich Null und dann hat man eine Abfrage mehr als nötig. Hunderte solcher Abfragen im Programm blähen den Code auf und verschwenden Platz im Cache und damit Ladezeit. Die Abfrage in delete pro Typ liegt jedoch fast immer schon im Cache.

    camper schrieb:

    Ich habe nichts dagegen, die Abfrage wegzulassen, halte diese Wahl aber eben nicht für so eindeutig besser, also schreibe ich optional. Ich glaube auch nicht, das das zu Verwirrung führt.

    Offensichtlich führt es zu Verwirrung, weil sehr viele die redundante Abfrage machen.


  • Mod

    Broly schrieb:

    Wenn ich im Destruktor den Speicherplatz freigebe, bevor ich die Membervariablen auf NULL setzte, stürzt das Programm ab. warum, weiß ich nicht.

    Dann ist das einer der zahlreichen Fehler, auf die du schon hingewiesen wurdest. Wenn du die Variablen auf 0 setzt und dann freigibst, geschieht wie erwähnt nichts. Es wird aber auch nichts freigegeben. Speicherloch, setzen, Sechs.

    solche Implementierungsansätzte

    DynArray( const DynArray& d, std::size_t capacity )
      : pfirst(new T[capacity]), plast(pfirst+std::min(d.size(), capacity)), <- ?
    

    noch nie gesehen 😮 .

    Das ist bloß eine Initialisierungsliste. Mal googlen. Ist nicht schwierig, aber wichtig.

    Aber da ich sie nicht so recht versteh, kann ich sie nicht einfach übernehmen, außerdem besteht sie nicht den Test, in der Test_Unit vom Prof.^^

    Du hast viele Fehler im Programm. Du wurdest auch schon auf die wichtigsten hingewiesen. Hast du sie bereinigt? Ich wette, Nein. Und falls ich damit Recht habe, sind insbesondere deine anderen Konstruktoren noch falsch.

    Meine Frage ist daher zur Funktion push_back, gibt es nicht einen
    Lösungsansatz, wobei man nicht einen weiteren Constructor überladen muss?

    Klar, mach einfach effektiv das gleiche, bloß alles in push_back. Das was camper gezeigt hat, ist die Logik aus meinem Algorithmus (meine erste Antwort) kombiniert mit dem Hinweis, die ganzen Reallokationen in eine Funktion zu packen (und zwar eine, die auch richtig(!) funktioniert). Das darfst du auch gerne umständlich ohne Zusatzfunktion machen, an das Grundrezept musst du dich aber schon halten.


  • Mod

    TyRoXx schrieb:

    camper schrieb:

    1. Symmetrie: zu jeder Deallokation gehört eine erfolgreiche Allokation (das ist das einzige Argument, das für mich persönlich relevant ist - Programme sollten lesbar bein)

    Als würde new einen Nullzeiger zurückgeben, wenn es fehlschlägt.

    Ich kann nicht folgen. Nochmal genau lesen.

    TyRoXx schrieb:

    camper schrieb:

    2. "Genau nix" ist immer noch ein Funktionsaufruf mehr als nötig

    Mikrooptimierungen rechtfertigen natürlich jeden Mist.
    Woher weißt du, ob nicht viel mehr Folgendes zutrifft: In den meisten Fällen ist der Zeiger ungleich Null und dann hat man eine Abfrage mehr als nötig. Hunderte solcher Abfragen im Programm blähen den Code auf und verschwenden Platz im Cache und damit Ladezeit. Die Abfrage in delete pro Typ liegt jedoch fast immer schon im Cache.

    Allgemeinplätze. Ich weiss es nicht, könnte auch umgekehrt sein. Geht am Thema vorbei.
    Nimmt man deine Argumentation wörtlich, bist du es, der durch Weglassen der Prüfung mikrooptimiert.

    TyRoXx schrieb:

    Offensichtlich führt es zu Verwirrung, weil sehr viele die redundante Abfrage machen.

    Ich kann nicht folgen.

    a oder b ist gleichermaßen möglich.
    viele machen b
    --------------
    es herrscht Verwirrung ??


  • Mod

    camper schrieb:

    a oder b ist gleichermaßen möglich.
    viele machen b
    --------------
    es herrscht Verwirrung ??

    Wie viele von denen, die b machen, können so wie du argumentieren, warum sie es machen? Du dürftest so ziemlich der einzige sein. Die anderen machen es bloß bei diesem Typen mit Ahnung im C++-Forum nach, auch wenn sie nicht verstehen, was es überhaupt soll.

    Aber lass uns das wirklich nicht nochmal aufwärmen. Ich bin schon ganz still und hätte dies hier gar nicht schreiben sollen, aber wo ich es sowieso schon getan habe, kann ich es auch absenden… 🙂


  • Mod

    SeppJ schrieb:

    ... hätte dies hier gar nicht schreiben sollen, aber wo ich es sowieso schon getan habe, kann ich es auch absenden… 🙂

    Für gewöhnlich bin ich auch zu faul, überhaupt darauf einzugehen 🙂

    SeppJ schrieb:

    Wie viele von denen, die b machen, können so wie du argumentieren, warum sie es machen?

    Genau das sollte imo der Sinn dieses Forums sein.
    Wofür sich jemand am Ende ist nicht wichtig, aber die Frage: "Warum?" sollte stets beantwortet werden können.
    Es sollten nicht einfach nur Lösungen vermittelt werden (die haben eine mehr oder minder kurze Halbwertszeit), sondern Grundlagen und Hintergründe.



  • camper schrieb:

    TyRoXx schrieb:

    camper schrieb:

    2. "Genau nix" ist immer noch ein Funktionsaufruf mehr als nötig

    Mikrooptimierungen rechtfertigen natürlich jeden Mist.
    Woher weißt du, ob nicht viel mehr Folgendes zutrifft: In den meisten Fällen ist der Zeiger ungleich Null und dann hat man eine Abfrage mehr als nötig. Hunderte solcher Abfragen im Programm blähen den Code auf und verschwenden Platz im Cache und damit Ladezeit. Die Abfrage in delete pro Typ liegt jedoch fast immer schon im Cache.

    Allgemeinplätze. Ich weiss es nicht, könnte auch umgekehrt sein. Geht am Thema vorbei.
    Nimmt man deine Argumentation wörtlich, bist du es, der durch Weglassen der Prüfung mikrooptimiert.

    Du hast mit den Optimierungen angefangen, die jetzt auf einmal "am Thema vorbeigehen".
    Durch Weglassen der Prüfung wird Redundanz vermieden. Das sollte wichtiger sein als hypothetische Mikrooptimierungen.
    Ich wollte nur zeigen, dass "ein Funktionsaufruf mehr als nötig" kein Argument für die Abfrage ist. Dass es mit Abfrage schneller ist, ist eine unbelegte Vermutung, genau wie meine Argumentation für das Weglassen der Abfrage.
    Ich wage mal zu behaupten, dass das stark von System und Compiler abhängt. Ein schlauer Compiler lässt das if vielleicht auch einfach weg.
    In jedem Fall spielt es keine Rolle, was schneller ist. Der Destruktor und das anschließende Freigeben des Speichers sind um Größenordnungen langsamer als ein Funktionsaufruf.
    Folglich gibt es kein Argument für die Abfrage. Das mit der "Symmetrie" hast du nicht erklärt, es liest sich wie wirres Zeug. Dass delete mit Null klarkommt, hat man wahrscheinlich von free übernommen. Und das verhält sich vermutlich so, weil Aufräum-Code häufig mit Nullzeigern zu tun hat.
    Die eingebaute Abfrage ist ein Feature von C++, eine Abstraktion. Man sollte nicht so tun als gäbe es die nicht.


  • Mod

    Ich bin nicht sicher, was daran schwer verständlich sein sollte, dass Ressourcen nur freigegeben werden können, sofern sie zuvor angefordert wurden.
    Der Versuch, Ressourcen die nicht angefordert wurden, zurückzugeben, ist danach ein Fehler (Nichts als Kategorie).
    Andererseits kann es sinnvoll sein, eine Menge Ressourcen freizugeben, auch wenn diese Menge zufällig leer ist (Nichts als Quantität).
    In Bezug auf Speicher kann in C++ beides ohne Umstände modelliert werden.

    TyRoXx schrieb:

    Die eingebaute Abfrage ist ein Feature von C++, eine Abstraktion. Man sollte nicht so tun als gäbe es die nicht.

    Macht ja auch keiner.

    Oder meinst du eher, dass man dieses Feature nutzen sollte, weil es einmal da ist? Dann interessiert mich, unter welcher Regel du diesen Schluss vom Sein aufs Sollen subsumierst.

    Reichst du beim Lotto deinen Tippschein auch dann ein, wenn du weisst, dass es eine Niete ist?



  • camper schrieb:

    Ich bin nicht sicher, was daran schwer verständlich sein sollte, dass Ressourcen nur freigegeben werden können, sofern sie zuvor angefordert wurden.
    Der Versuch, Ressourcen die nicht angefordert wurden, zurückzugeben, ist danach ein Fehler (Nichts als Kategorie).
    Andererseits kann es sinnvoll sein, eine Menge Ressourcen freizugeben, auch wenn diese Menge zufällig leer ist (Nichts als Quantität).
    In Bezug auf Speicher kann in C++ beides ohne Umstände modelliert werden.

    Was hat das mit delete[] zu tun?

    camper schrieb:

    TyRoXx schrieb:

    Die eingebaute Abfrage ist ein Feature von C++, eine Abstraktion. Man sollte nicht so tun als gäbe es die nicht.

    Macht ja auch keiner.

    Doch, mit der Abfrage tut man das. Das ist so ähnlich wie while ((i != 0) == true) . Kann man machen, sollte man aber nicht.

    camper schrieb:

    Oder meinst du eher, dass man dieses Feature nutzen sollte, weil es einmal da ist? Dann interessiert mich, unter welcher Regel du diesen Schluss vom Sein aufs Sollen subsumierst.

    Was willst du eigentlich? delete[] hat Eigenschaften, die man bei der Benutzung beachten sollte. Ich behaupte nicht, dass man delete[] jemals benutzen sollte oder dass seine Eigenschaften immer gut sind.

    camper schrieb:

    Reichst du beim Lotto deinen Tippschein auch dann ein, wenn du weisst, dass es eine Niete ist?

    Millionen Menschen tun das, ich nicht.
    Was hat das mit delete[] zu tun?


  • Mod

    TyRoXx schrieb:

    camper schrieb:

    Ich bin nicht sicher, was daran schwer verständlich sein sollte, dass Ressourcen nur freigegeben werden können, sofern sie zuvor angefordert wurden.
    Der Versuch, Ressourcen die nicht angefordert wurden, zurückzugeben, ist danach ein Fehler (Nichts als Kategorie).
    Andererseits kann es sinnvoll sein, eine Menge Ressourcen freizugeben, auch wenn diese Menge zufällig leer ist (Nichts als Quantität).
    In Bezug auf Speicher kann in C++ beides ohne Umstände modelliert werden.

    Was hat das mit delete[] zu tun?

    um...
    Speicher ist ein Ressource.
    delete gibt Speicher frei.
    delete kann auch auf Nullzeiger angewandt werden.
    Nullzeiger können repräsentieren, dass nie Speicher angefordert wurde.

    TyRoXx schrieb:

    camper schrieb:

    TyRoXx schrieb:

    Die eingebaute Abfrage ist ein Feature von C++, eine Abstraktion. Man sollte nicht so tun als gäbe es die nicht.

    Macht ja auch keiner.

    Doch, mit der Abfrage tut man das. Das ist das so ähnlich wie while ((i != 0) == true) . Kann man machen, sollte man aber nicht.

    "Man sollte nicht so als gäbe es die nicht." -> "so tun als ob" impliziert Intention oder Wille. Dein while-Beispiel deutet eher auf Unwissenheit oder Ignoranz hin. Weil also nicht klar ist, was du eigentlich sagen wolltest, habe ich die Aussage erst einmal wörtlich interpretiert.

    TyRoXx schrieb:

    camper schrieb:

    Oder meinst du eher, dass man dieses Feature nutzen sollte, weil es einmal da ist? Dann interessiert mich, unter welcher Regel du diesen Schluss vom Sein aufs Sollen subsumierst.

    Was willst du eigentlich? delete[] hat Eigenschaften, die man bei der Benutzung beachten sollte. Ich behaupte nicht, dass man delete[] jemals benutzen sollte oder dass seine Eigenschaften immer gut sind.

    Das ist die zweite Interpretation. Was du sagst, ist im Prinzip:
    X hat die Eigenschaft A. Also sollte man die Eigenschaft A ausnutzen. (X=delete; A=kann auch mit Nullzeigern genutzt werden)
    Das ist (ohne eine entsprechende Ableitungsregel) ein Trugschluss.

    TyRoXx schrieb:

    camper schrieb:

    Reichst du beim Lotto deinen Tippschein auch dann ein, wenn du weisst, dass es eine Niete ist?

    Millionen Menschen tun das, ich nicht.
    Was hat das mit delete[] zu tun?

    Es ist ein anschauliches, analoges Beispiel.



  • camper schrieb:

    TyRoXx schrieb:

    camper schrieb:

    Oder meinst du eher, dass man dieses Feature nutzen sollte, weil es einmal da ist? Dann interessiert mich, unter welcher Regel du diesen Schluss vom Sein aufs Sollen subsumierst.

    Was willst du eigentlich? delete[] hat Eigenschaften, die man bei der Benutzung beachten sollte. Ich behaupte nicht, dass man delete[] jemals benutzen sollte oder dass seine Eigenschaften immer gut sind.

    Das ist die zweite Interpretation. Was du sagst, ist im Prinzip:
    X hat die Eigenschaft A. Also sollte man die Eigenschaft A ausnutzen. (X=delete; A=kann auch mit Nullzeigern genutzt werden)
    Das ist (ohne eine entsprechende Ableitungsregel) ein Trugschluss.

    Wow, wir sind schon bei der Philosophie angekommen. Wenn du nichts mehr über C++ zu sagen hast, sind wir ja fertig.

    camper schrieb:

    TyRoXx schrieb:

    camper schrieb:

    Reichst du beim Lotto deinen Tippschein auch dann ein, wenn du weisst, dass es eine Niete ist?

    Millionen Menschen tun das, ich nicht.
    Was hat das mit delete[] zu tun?

    Es ist ein anschauliches, analoges Beispiel.

    Ich frage mich so langsam wer hier die Niete ist.

    EDIT: Ah, du meinst den Zettel, mit dem man seinen Gewinn abholen kann.
    Das unnötige Prüfen des Scheins entspricht in meinen Augen eher einem assert(ptr) , wenn die Programmlogik das hergibt. Beides kostet nichts und kann in Ausnahmefällen helfen.
    Die Abfrage vor delete bringt aber nichts, gar nichts, unter keinen Umständen nie und niemals. Das ist wie das Einreichen einer Rolle Klopapier bei der Lottostelle. Du kannst noch so viel Klopapier herbeischleppen, aber du wirst höchstens einen Tritt in den Hintern gewinnen (= Redundanz, schlechte Lesbarkeit, Verwirrung).
    Wo hier die Analogie zu deinen Gunsten ist, weiß ich immer noch nicht.
    Ist die Niete etwa ein Nullzeiger und delete das Einreichen? Wie gesagt, delete überprüft, ob du gewonnen hast.
    delete ist die LottoCard von C++.


  • Mod

    TyRoXx schrieb:

    Wow, wir sind schon bei der Philosophie angekommen.

    Es tut mir leid, wenn du damit überfordert bist.

    TyRoXx schrieb:

    Wenn du nichts mehr über C++ zu sagen hast, sind wir ja fertig.

    Das glaube ich auch. Wenn du meinst, Logik über Bord werfen zu können, weil du ja sowieso recht hast.

    TyRoXx schrieb:

    Die Abfrage vor delete bringt aber nichts, gar nichts, unter keinen Umständen nie und niemals.

    Ich sehe das anders. Da es gerade um diese Frage geht, taugt diese Behauptung nicht als Argument.


  • Mod

    Könnt ihr bitte zum Threadthema zurück kommen, insbesondere wenn eure Argumente an der Grenze zu persönlichen Beleidigungen angekommen sind (*TyRoXx anguck*)? Falls ihr weiter dieses Thema diskutieren wollt, spalte ich es hier ab oder macht selber einen neuen Thread auf. Aber ich glaube, es gibt nichts neues zu sagen, was hier im Forum nicht schon 1000x gesagt worden ist (Und TyRoXx hat sowieso Recht, er kann nur nicht gut diskutieren :p ).


Anmelden zum Antworten