Die weit verbreitete Verwendung von shared_ptr wird fast zwangsläufig unerwünschte und ungesehene Speicherbelegung verursachen.
Zyklische Referenzen sind eine bekannte Ursache und einige von ihnen können indirekt und schwer zu erkennen sein, besonders in komplexem Code, der von mehr als einem Programmierer bearbeitet wird; Ein Programmierer kann entscheiden, dass ein Objekt einen Verweis auf einen anderen benötigt, um eine schnelle Lösung zu finden, und hat keine Zeit, den gesamten Code zu untersuchen, um zu sehen, ob er einen Zyklus schließt. Diese Gefahr wird stark unterschätzt.
Weniger gut verstanden ist das Problem von unveröffentlichten Referenzen. Wenn ein Objekt an viele shared_ptrs verteilt wird, wird es nicht zerstört, bis jeder von ihnen auf Null gesetzt ist oder den Gültigkeitsbereich verlässt. Es ist sehr leicht, eine dieser Referenzen zu übersehen und am Ende mit Objekten zu enden, die unsichtbar in der Erinnerung liegen und von denen du dachtest, dass du damit fertig bist.
Obwohl streng genommen sind dies keine Speicherlecks (es wird alles freigegeben werden, bevor das Programm beendet wird) sie sind genauso schädlich und schwerer zu erkennen.
Diese Probleme sind die Folgen von sinnvollen falschen Deklarationen: 1. Deklarieren Sie, was Sie wirklich als Single-Besitz als shared_ptr sein möchten. scoped_ptr wäre korrekt, aber jeder andere Verweis auf dieses Objekt muss ein roher Pointer sein, der frei gelassen werden könnte. 2. Deklarieren Sie, was Sie wirklich als passive Beobachtungsreferenz sehen möchten, als shared_ptr. weak_ptr wäre korrekt, aber dann haben Sie die Mühe, es jedes Mal in share_ptr zu konvertieren, wenn Sie es verwenden möchten.
Ich vermute, dass Ihr Projekt ein gutes Beispiel für die Art von Ärger ist, in die Sie diese Praxis bringen kann.
Wenn Sie eine speicherintensive Anwendung haben, benötigen Sie wirklich nur eine einzige Eigentümerschaft, damit Ihr Entwurf die Lebensdauer von Objekten explizit steuern kann.
Mit Einzelbesitz opObject = NULL; wird definitiv das Objekt löschen und es wird es jetzt tun.
Mit gemeinsamem Besitz spObject = NULL; ........ wer weiß? ......
Vielen Dank! Es gibt ungefähr 200 Tausende Zeilen. Es ist also schwierig, jedes neue ... zu überprüfen. Gibt es ein Compiler-Makro, um die Ref-Check-Fähigkeit von Boost zu aktivieren (wenn eine solche Fähigkeit vorhanden ist). Der Speicher verursacht durch Programmierungslogik Fehler über Pools, ich bin sicher, aber ich kann es einfach nicht finden. – user25749
Sie können immer noch Speicherlecks mit shared_ptrs haben. Erstellen Sie eine zyklische Referenz und sie wird nie gelöscht, selbst wenn der Rest der App nicht mehr darauf verweist. Instant Speicherleck! – jalf
Ein Verweis auf ein Objekt, das falsch beibehalten wird, ist immer noch ein Ressourcenverlust. Dies ist der Grund, warum GC-Programme immer noch Lecks haben können, normalerweise aufgrund des Observer-Musters - der Beobachter ist auf einer Liste statt der Observablen und wird nie aus ihm genommen. Letztendlich wird ein 'remove' für jedes' add' benötigt, genauso wie ein 'delete' für jedes' new' benötigt wird. Genau der gleiche Programmierfehler, der genau das gleiche Problem verursacht. Eine "Ressource" ist eigentlich nur ein Paar von Funktionen, die mit entsprechenden Argumenten gleich oft aufgerufen werden müssen, und ein "Ressourcenleck" ist das, was passiert, wenn Sie dies nicht tun. –