Eure Erfahrungen mit shared, weak... Pointern
-
Dravere schrieb:
@DStefan,
Nur ein Anfänger hat Probleme mit new/delete. Ich persönlich hatte schon lange keine Speicherlecks mehr, keine doppelten delete, die Verantwortung für den Speicher ist immer ganz klar aufgetrennt, nämlich derjenige, welcher den Speicher anfordert, gibt den Speicher auch wieder frei. Ich mag mich nicht an den letzten Absturz wegen eines solchen Fehlers erinnern.Und ich verwende
boost::shared_ptrkaum! Es ist nur eine Frage des Designs des Programmes und der Erfahrung des Programmierers. Wen jemandboost::shared_ptrverwendet, um seine Defizite in Erfahrung und dem Design des Programmes auszugleichen, dann ist dies so ziemlich der falsche Weg.Grüssli
Sieh an! Ich hatte immer gedacht, es sei genau anders herum: Erfahrene Programmierer verwenden Smart-Pointer, weil sie genau wissen, was sie daran haben.
Ich brauche keine klare "Auftrennung" der Verantwortung für ein Objekt, weil es automaitsch gelöscht wird, wenn's keiner mehr verwendet. Ich braucht mein Design nicht zu verändern, bloß um sicher zu stellen, das für jedes new() auch bestimmt genau ein delete() erfolgt. Das führt in der Regel zu klarerem Design. Ich brauche mich beim Auftreten von Exceptions nicht darum zu kümmern, dass aller angeforderter Speicher auch in diesem Fall korrekt freigegeben wird.
Kurz: Ich habe kapiert, was RAII bedeutet. Und ich verschwende keine Zeit damit, mir über Probleme Gedanken zu machen, die fast immer durch Verwendung von Smart Pointern vermieden werden können. Da gib's wichtigeres.
Stefan.
-
DStefan schrieb:
Sieh an! Ich hatte immer gedacht, es sei genau anders herum: Erfahrene Programmierer verwenden Smart-Pointer, weil sie genau wissen, was sie daran haben.
1. Erfahrene Programmierer setzen die Mittel an den Stellen ein, wo sie auch sinnvoll sind. Das heisst im allgemeinen aber nicht, dass man nur noch
shared_ptroder Smart-Pointer verwendet. Das zeugt meistens eher von schlechten Programmierern, welche nicht ausgewogen oder überlegt programmieren.
2. Ich habe vonshared_ptrgeredet, dass ist ein himmelweiter Unterschied zu Smart-Pointern. Der Shared-Pointer ist nur einer von vielen verschiedenen Smart-Pointern.Für RAII braucht man keinen
shared_ptr, sondern meistens wenn schon einenscoped_ptr/auto_ptroder im zukünftigen Standard denunique_ptr.
Und wenn ich dich also richtig verstanden habe, dann hast du lieber ein schlechtes Design, dafür eine einfache Handhabung von Speicher? Na gut, ich habe lieber eine gut durchdachte Bibliothek.
Einshared_ptrist meistens gar nicht nötig und bedeutet nur einen unnötigen Overhead. Es ist ja auch sehr typisch für C++, dass man im allgemeinen sowieso kaum Zeiger benötigt und wenn, dann sind sie meistens sehr eng an Klassen oder einem Scope gekapselt. Wodurch sich dann eher einscoped_ptranbietet.
Sonstige Speicherverwaltung wird in C++ auch oft Containern überlassen. Was allerdings auch wieder ein typisches Beispiel ist, wo intern Zeiger verwendet werden, welche an eine Klasse gebunden sind, wodurchshared_ptrunötig ist. Zum Teil ist in solchen Fällen sogar einscoped_ptrhinderlich. RAII kann aber trotzdem gewährleistet werden, durch das hinzufügen eines eigenen Destruktors.Grüssli
-
Habt ihr schon shared Pointer und Co in größeren Projekten eingesetzt? Gabs Probleme mit anderen Frameworks oder sonstigem oder hat alles gut funktioniert?
Ja ich habe schon in größeren Projekten Erfahrungen damit gemacht.
Das war übrigens meine erste erwähnenswerte Erfahrung und diese war nicht wirklich erfreulich.Wir hatten heftigste Probleme mit Zirkeln, so daß Speicher gar nicht freigegeben wurde. Weiterhin kam es dazu dass Objekte im falschen Thread Context freigegeben wurden. Das Programm hing, stürzte ab, hatte Memory leaks, ...
Die erste Funktion die ich verwendet habe war mir den Refence Count anzeigen zu lassen.
Als zweites hatte ich einen ObjectTracer implementiert in den jede kreierte Klasse eingetragen und beim Zertören ausgetragen wurde.
Schließlich hatte ich etliche Member, Funktionen und Methoden von Shared Pointer auf Weak Pointer umgestellt. Erst dann lief das Programm stabil.Fazit ?
Genau die selben Probleme wie mit normalen Pointer
Und es kommt nach wie vor auf ein vernünftiges Design und den Programmierer an.Gruß Frank
-
DStefan schrieb:
Dravere schrieb:
@DStefan,
Nur ein Anfänger hat Probleme mit new/delete. Ich persönlich hatte schon lange keine Speicherlecks mehr, keine doppelten delete, die Verantwortung für den Speicher ist immer ganz klar aufgetrennt, nämlich derjenige, welcher den Speicher anfordert, gibt den Speicher auch wieder frei. Ich mag mich nicht an den letzten Absturz wegen eines solchen Fehlers erinnern.Und ich verwende
boost::shared_ptrkaum! Es ist nur eine Frage des Designs des Programmes und der Erfahrung des Programmierers. Wen jemandboost::shared_ptrverwendet, um seine Defizite in Erfahrung und dem Design des Programmes auszugleichen, dann ist dies so ziemlich der falsche Weg.
GrüssliSieh an! Ich hatte immer gedacht, es sei genau anders herum: Erfahrene Programmierer verwenden Smart-Pointer, weil sie genau wissen, was sie daran haben.
Würde ich nicht so sagen.
Ich verwendeboost::shared_ptrnie.
-
skyPilot schrieb:
Habt ihr schon shared Pointer und Co in größeren Projekten eingesetzt? Gabs Probleme mit anderen Frameworks oder sonstigem oder hat alles gut funktioniert?
Ich habe mit dem shared_ptr recht gute Erfahrungen gemacht, auch wenn es schon richtig ist, das man diesen nicht überall einsetzen sollte. Ein relativ aktuelles Problem wo ich shared_ptr eingesetzt habe ist eine Stelle bei der nicht genau gesagt werden kann wann die Daten zu löschen sind (Und da wüsste ich jetzt keine sauberere Lösung als shared_ptr). shared_ptr sind gut, aber man sollte immer die Kosten (und Fallstricke) berücksichtigen.
Was ich wiederum recht massiv verwende sind scoped_ptr.
-
shared_ptr<> vermeide ich, wann möglich; die externe Referenzzählung ist selten die beste oder sauberste Lösung. Wenn ich schon automatisches Speichermanagement verwende, dann nach Möglichkeit intrinsische Referenzzählung a la COM.
auto_ptr<> allerdings kommt bei mir dauernd vor.
-
shared_ptrhabe ich sehr selten.
scoped_ptrbenutze ich hingegen recht oft, für RAII und Exceptionsicherheit ist er sehr geeignet.
auto_ptrhab ich auch ab und zu, allerdings eher bei Factory-Methoden mit automatischer Freigabe.
-
Nexus schrieb:
shared_ptrhabe ich sehr selten.
scoped_ptrbenutze ich hingegen recht oft, für RAII und Exceptionsicherheit ist er sehr geeignet.Die habe ich bisher beide nicht eingesetzt. Das liegt aber wohl auch der Art der Anwendungen (hauptsächlich "number chrunching"). Bei scoped_ptr vermisse ich irgendwie eine release()-Funktion, mit der ich den Zeiger "befreien" kann, ohne dass das Objekt gelöscht wird. Mit dem kommenden unique_ptr wird auto_ptr und scoped_ptr dann wohl überflüssig.
Nexus schrieb:
auto_ptrhab ich auch ab und zu, allerdings eher bei Factory-Methoden mit automatischer Freigabe.Geht mir auch so. Das ist meiner Meinung nach auch eine gute Dokumentationsmöglichkeit über die Besitzverhältnisse im Code selbst. Der Aufrufer weiß dann, dass er selbst für die Verwaltung der Lebenszeit verantwortlich ist.
Gruß,
SP
-
Sebastian Pizer schrieb:
Bei scoped_ptr vermisse ich irgendwie eine release()-Funktion, mit der ich den Zeiger "befreien" kann, ohne dass das Objekt gelöscht wird.
Du kannst dir ja schnell einen eigenen
scoped_ptrbasteln, das sollte nicht schwer sein (wenn du es wirklich brauchst).Ich habe mir auch mal einen eigenen Smart Pointer geschrieben, der im Gegensatz zu den üblichen Smart Pointers eine Kopiersemantik besitzt (wird der Zeiger kopiert, so wird das Objekt dahinter kopiert). Habe ich zwar noch nie wirklich produktiv eingesetzt, aber zum Beispiel für das Pimpl-Idiom könnte ich mir eine Anwendung vorstellen (damit die Klasse nicht gleich die grossen Drei implementieren muss). Oder generell, um Header-Abhängigkeiten zu verhindern, da bei Zeigern eine Vorwärtsdeklaration ausreicht.
-
Frank Erdorf schrieb:
Schließlich hatte ich etliche Member, Funktionen und Methoden von Shared Pointer auf Weak Pointer umgestellt. Erst dann lief das Programm stabil.
Fazit ?
Genau die selben Probleme wie mit normalen Pointer
Und es kommt nach wie vor auf ein vernünftiges Design und den Programmierer an.Gruß Frank
Yep, einmal an der falschen Stelle nen shared, statt nem weak Pointer in ner Klasse und schon gabs ein Memleak.