frage zu heap allozierung ...



  • Mir fällt auch schlagartig kein einfaches Beispiel ein, wo dies unbedingt notwendig essentiell so gemacht werden muss.

    Es geht auch nicht um die einfachen Beispiele, da bin ich vollkommen mit Dir einverstanden. Aber wir haben zB. Maschinen mit ganz unterschiedlichen Handlingsystemen von manueller Zuführung bis zu SPS gesteuerten Handlern. Da liest die CreateObject() funktion des virtuellen Handlers die Konfiguration (XML Datei) und erzeugt den richtigen Handler.

    Natürlich ist das alles schön gekapselt und man arbeitet im Programm mit Referenzen, aber im Kern gibts die CreateObject () und die Destroy () Funktion.

    Herzliche Grüsse
    Walter



  • Ausserdem fände ich eine globale Freigabefunktion im Hinblick auf die globale Erzeugungsfunktion symmetrischer als eine Memberfunktion

    Nur das Objekt selber weiss wie es sich zerstören muss.

    Man kann da mit viel Aufwand sicher etwas bauen, aber wir Programmierer haben ja ein Gehalt 😉

    Herzliche Grüsse
    Walter



  • Meine Aussagen haben sich mehr auf public-Methoden bezogen. Bei privaten Methoden die innerhalb einer Klasse sich selbst verwalten habe ich wenig gegen Zeiger.

    Die Frage des Autors sah für mich implizit anders aus, dass er eine Klasse verwendet die ein Heap-Objekt nach außen gibt, was ich nicht befürworten kann und will^^



  • weicher schrieb:

    Nur das Objekt selber weiss wie es sich zerstören muss.

    Das ist unlogisch. Das Objekt wurde von einer anderen Funktion erzeugt. Nur die Funktion weiss, wie die Zerstörung zu erfolgen hat, sofern du nicht irgendwelche Querabhängigkeiten hast.

    Beispiel:

    Object* Factory1()
    {
        return new Object();
    }
    
    Object* Factory2()
    {
        void* memory = std::malloc(sizeof(Object));
        new (memory) Object();
        return static_cast<Object*>(memory);
    }
    
    Object* Factory3()
    {
        myObjectList.push_back(Object());
        return &myObjectList.back();
    }
    

    Was schreibst du nun in den Destruktor? Ihr werdet euch zwar auf eine Allokationsmethode festgelegt haben. Aber dass diese nur das Objekt selbst kennt, kann nicht sein, da es sich nicht selbst erzeugen kann (und die Deallokation symmetrisch zur Allokation sein muss).

    Insofern denke ich eher, dass die Symmetrie sogar weniger Aufwand mit sich brächte, weil sich die Allokations- und Deallokationsfunktion im gleichen Modul befinden und du bei einer neuen Implementierung nicht an verschiedenen Stellen Code ändern musst.



  • Ich habe natürlich immer mein Framework im Kopf und da ist das releasen des Speichers der kleinste Teil beim zerstören eines Objekts.

    Da dieser Thread aber nur die heap allozierung behandelt bin ich damit eigentlich schon off Topic. Ich denke nur, man kann das nicht so isoliert betrachten, Objekte sind IMHO viel mehr als nur allozierter Speicher.

    Als ich diesen Thread gesehen habe war ich am implementieren eines Fensters welches in eine DLL ausgelagert ist und da ist die Kombination von Create() und obj->Destroy() die einfachste Möglichkeit das Dingens wieder sauber loszuwerden.

    Ich weiss, das ist jetzt etwas speziell. Aber das ist eigentlich genau der Punkt. Auf die Pauschale ablehnung von Sprachmitteln (über)reagiere ich etwas allergisch 😉

    Kein Schreiner wird je Sagen "Verwende NIE und NIMMER die Kreissäge, damit kannst Du Dir die Finger absägen!". Warum Programmierer genau das immer wieder tun ist mir ein Rätsel. Was passiert denn schon schlimmes wenn mal ein Pointer ins Nirwana zeigt oder man ein Memoryleak einbaut.

    Das Programm stürzt beim ersten vernünftigen Test ab... Es gibt keine Verletzen und es fliesst kein Blut und man hat alle Werkzeuge um den Fehler zu beheben.

    Herzliche Grüsse
    Walter



  • weicher schrieb:

    Man kann es so machen, dass klar ist wie man damit umgehen muss.

    Ich mach es zB. immer so:

    obj* Object ();
    

    oder

    obj* GetObject ();
    

    der gelieferte Pointer muss nicht entsorgt werden.

    obj* CreateObject ();
    

    der gelieferte Pointer muss mit

    obj->Destroy ()
    

    entsorgt werden.

    Ich stimme Dir zumindest in dem Punkt zu, dass man sich überlegen sollte, wie man Funktions-Deklarationen bzgl "Besitz von Objekten" selbstdokumentierent gestalten kann. In C++0x würde ich das so machen:

    Rohe Zeiger: Kein Ownership-Transfer (per Konvention).
    unique_ptr: Ownership-Transfer (ergibt aus dem Verhalten von unique_ptr).

    Also, ohne Ownership-Transfer:

    clazz* get_obj();
    void set_obj(clazz*);
    

    und mit Ownership-Transfer:

    unique_ptr<clazz> get_obj();
    void set_obj(unique_ptr<clazz>);
    

    Gruß,
    kk



  • weicher schrieb:

    Was passiert denn schon schlimmes wenn mal ein Pointer ins Nirwana zeigt oder man ein Memoryleak einbaut.

    Das Programm stürzt beim ersten vernünftigen Test ab...

    Wenn das deine Einstellung ist, hast du in der Diskussion wohl nicht soviel verloren. Durchaus legitim, aber das sehen viele anders, und mit Sicherheit sehr viele von denen, die C++ heute noch die Treue halten (und nicht nur Legacy-Code warten müssen.)
    Wie du ein Speicherleck durch einen Absturz finden willst, musst du aber noch verraten.



  • und nicht nur Legacy-Code warten müssen

    Ich warte nicht nur legacy Code, ich bin daran mein Framework für die aktuelle Compilergeneration praktisch neu zu schreiben und Du würdest staunen wieviele Überprüfungen da eingebaut sind 😉

    Normalerweise gibts bei Memoryleaks keinen Absturz aber auch das habe ich schon erlebt und es dauerte nach dem Start gar nicht so lange bis nichts mehr gieng.

    Aber für Memoryleaks gibt es neben dem Debugger auch noch andere Werkzeuge um sie zu entdecken. Man muss sie nur Anwenden.

    Aber Du verstehst mich falsch, ich sage nicht man soll einfach unbedacht jedes Sprachmittel einsetzen. Wenn es die Möglichkeit gibt etwas abzusichern dann soll man das tun. Aber nach mehr als 30 Jahren Programmieren weiss ich einfach, dass selbst die besten Schutzmechanismen nichts gegen einen unbedachten Programmierer ausrichten können aber vielfach den bedachten und sorgfältigen Programmierer stark behindern.

    Wenn das deine Einstellung ist, hast du in der Diskussion wohl nicht soviel verloren

    Ich habe jetzt auch alles gesagt 😃

    Herzliche Grüsse
    Walter



  • weicher schrieb:

    Das Programm stürzt beim ersten vernünftigen Test ab...

    Schön wäre es.
    Ich hab über Weihnachten einen Bug aus unserer Software entfernt der irgendwann zwischen 1995 und 1998 da rein kam.

    Von den Bugs die mittlerweile ein "Feature" sind weil das Verhalten der Software mittlerweile vom Kunden so erwartet wird, rede ich garnicht erst...

    Leider sind die wenigsten Bugs so nett und zeigen sich sofort.



  • weicher schrieb:

    Normalerweise gibts bei Memoryleaks keinen Absturz aber auch das habe ich schon erlebt und es dauerte nach dem Start gar nicht so lange bis nichts mehr gieng.

    Ja klar, aber du hattest gesagt, Memoryleaks seien kein Problem, weil sie eh auffallen. Das ist meiner Erfahrung nach in der Regel nicht der Fall, kleine Memoryleaks werden einfach hingenommen. Man sucht die in der Praxis nicht akribisch, die einzige Möglichkeit, sie zu beseitigen, besteht darin, sie von vornherein nicht entstehen zu lassen.

    Aber Du verstehst mich falsch, ich sage nicht man soll einfach unbedacht jedes Sprachmittel einsetzen.

    Mag sein, dass du das außerdem gesagt hast. Ich wende mich gegen deine Aussage, Speicherlecks und ungültige Zeiger seien völlig unproblematisch.



  • Ich kann euch da nicht verstehen. Gegen Schweineren auf dem Heap gibt es Werkzeuge. Wieso muss man darüber diskutieren?



  • weicher schrieb:

    Was passiert denn schon schlimmes wenn mal ein Pointer ins Nirwana zeigt oder man ein Memoryleak einbaut.

    Meinst du das ernst?

    weicher schrieb:

    Aber für Memoryleaks gibt es neben dem Debugger auch noch andere Werkzeuge um sie zu entdecken. Man muss sie nur Anwenden.

    Das beste Werkzeug gegen Memory Leaks ist RAII. Man muss es nur anwenden. Wenn man irgendwelche Zusatztools wie valgrind braucht, um Memory Leaks zu beheben, hat man schon längst etwas falsch gemacht. Zumindest im Grossteil der Fälle.

    Eine moderne C++-Anwendung ist memory-leak-frei, ohne dass man speziell etwas dafür tun muss. Dass das bei antikem Code anders aussehen kann, verstehe ich, aber verallgemeinere das bitte nicht.

    weicher schrieb:

    Aber nach mehr als 30 Jahren Programmieren weiss ich einfach, dass selbst die besten Schutzmechanismen nichts gegen einen unbedachten Programmierer ausrichten können aber vielfach den bedachten und sorgfältigen Programmierer stark behindern.

    Vielleicht verstehen wir unter Schutzmechanismen nicht das Gleiche. Aber Konstrukte wie std::tr1::array , std::vector , boost::scoped_ptr machen das Leben allen Programmierern leichter, sofern sie sinnvoll eingesetzt werden.



  • Ich kanns mir doch nicht verklemmen 😉

    Ich habe gesagt: "Was passiert denn schon schlimmes"

    Du hast gelesen:
    seien kein Problem
    seien völlig unproblematisch.

    Was ist schlimm:
    Finger ab.
    Job weg.

    Was ist ein dangling Pointer:
    ärgerlich

    Was ist ein memory leak:
    unangenehm und eine Herausforderung.

    Zumindest im Grossteil der Fälle.

    Eben

    sofern sie sinnvoll eingesetzt werden.

    Eben

    Herzliche Grüsse
    Walter



  • weicher schrieb:

    Was ist ein dangling Pointer:
    ärgerlich

    Zeitraubend, nervenaufreibend, einfach nur unnötig. Gleiches für das Memory Leak. Gerade weil es derart einfache Techniken gibt, um solche Fehler auszumerzen, ist die Mühe einfach nicht gerechtfertigt.

    weicher schrieb:

    Zumindest im Grossteil der Fälle.

    Eben

    Natürlich behauptet jeder, er würde zu den Ausnahmefällen gehören. Ist immer so, auch bei den Spaghetticodern mit goto .

    weicher schrieb:

    sofern sie sinnvoll eingesetzt werden.

    Eben

    Hm, was ist wohl schwieriger. Eine fertige, selbst-verwaltende Klasse einzusetzen oder einen besitzenden Zeiger mit manueller Speicherverwaltung? Eure Memory Leaks und Dangling Pointers liefern da eine klare Antwort, fürchte ich.



  • Eure Memory Leaks und Dangling Pointers liefern da eine klare Antwort, fürchte ich.

    Jetzt habe ich plötzlich noch Dangling Pointers und Memory Leaks 😉

    Herzliche Grüsse
    Walter



  • weicher schrieb:

    Was ist schlimm:
    Finger ab.
    Job weg.

    Kunde weg? Weil Software regelmäßig neugestartet werden muss weil sie entweder abstürtzt oder zu langsam wird?



  • Kunde weg?

    Kann mir nicht passieren. Alle Programme sind für die Produktionsmaschinen unserer eigenen Quarzproduktion.

    Einige Daten:
    Betrieb läuft 7/24
    Pro Tag werden ca. 2'000'000 Quarze Produziert.
    10 verschiedene Programme laufen in unterschiedlichen Konfigurationen auf über 300 Maschinen in 3 Fabriken weltweit.

    Die Schichtleiter haben meine private Telefon Nummer und rufen auch mitten in der Nacht an wenn etwas nicht mehr läuft. Seit mehr als 10 Jahren bin ich nie mehr geweckt worden.

    Die wirklichen Probleme welche immer wieder Kopfzerbrechen machen haben mit C++ oder Heap oder Pointern gar nicht's zu tun.

    Meine Hitparade:
    1. RS232 Ein Standard bei welchem jeder macht wies im gerade passt. Das fängt beim Kabel an und hört bei der Dokumentation nicht auf.
    2. Problembeschreibungen aus der Produktion welche nur etwas mit dem aktuellen Problem aber nichts mit der ganzen Realität zu tun haben.
    3. Änderungen am Produktdesign ohne Vorwarnung, wunderbar für Machine Vision.
    4. Dongles von eingekauften Bibliotheken welche plötzlich nicht mehr funktionieren.

    Herzliche Grüsse
    Walter



  • weicher schrieb:

    Kann mir nicht passieren. Alle Programme sind für die Produktionsmaschinen unserer eigenen Quarzproduktion.

    Einige Daten:
    Betrieb läuft 7/24
    Pro Tag werden ca. 2'000'000 Quarze Produziert.
    10 verschiedene Programme laufen in unterschiedlichen Konfigurationen auf über 300 Maschinen in 3 Fabriken weltweit.

    dh ein Fehler stoppt nur die Produktion? Ja, das fällt sicher nicht unter "schlimm".



  • dh ein Fehler stoppt nur die Produktion?

    Ja, das ist tatsächlich so. Aber es ist seit sehr sehr langer Zeit so, dass die Stillstände nicht durch die Programme sondern durch mechanische Abnutzung ausgelöst werden.

    Wir schludern ja nicht, im Gegenteil wir geben uns sehr grosse Mühe die Programme sicher und wartbar zu machen. Auch beim schreiben des Quellcodes legen wir grössten Wert auf eine saubere Darstellung inklusive Dokumentation. Und natürlich setzen wir auch all die Dinge wie std:vector, std::map usw. ein.

    Aber wenns sein muss, und bei Hardwarenaher Programmierung und DLL's muss es einfach manchmal sein, dann setzen wir auch Pointer ein. Wie der Schreiner an der Kreissäge, sind wird im Umgang mit Pointern sehr vorsichtig und testen solche Module gründlich aus. Wir leiden einfach nicht an einer Pointerphobie 😉

    Herzliche Grüsse
    Walter



  • Es geht hier auch nicht darum ob der code den ihr verwendet korrekt ist, sondern ob ein wilder Zeiger und memory leaks "schlimm" sind oder nicht.

    Produktionsstillstand halte ich für schlimm. ergo sind wilde Zeiger und memory leaks schlimm.


Anmelden zum Antworten