[for_each] Adressen der Elemente behandeln
-
Hallo,
ich habe einen STL Container mit raw-Zeigern:
std::list<X*> container;Und möchte gerne alle Speicherbereiche sicher freigeben, auf die die in "container" gespeicherten Elemente zeigen, ungefähr so:
template <typename T> void SafeDelete(T** ppT) // MSDN { if (*ppT) { delete *ppT; *ppT = NULL; } } for_each(container.begin(), container.end(), SafeDelete<X>);Natürlich meckert der Compiler rum, denn SafeDelete erwartet ja die Adresse des Zeigers (um diesen danach auf NULL setzen zu können).
Kann man mit for_each irgendwie die Adressen der Elemente behandeln?
-
Benötigst du wirklich raw pointer in deiner Collection? Ist nicht ein Smart pointer besser geeignet?
MfG SideWinder
-
Das
SafeDelete()ist für gar nichts. Du musst weder vor demdeleteaufNULLprüfen noch nach demdeleteaufNULLsetzen.deletealleine reicht.Davon abgesehen sollte die Funktion einen Zeiger als Parameter nehmen, wenn Zeiger gespeichert werden. Aber sinnvoller ist es, gleich entsprechende Container zu verwenden, z.B. Boosts Pointer-Container.
-
+1 für Boost Pointer Container.
-
Dieses Safe-Delete Dings sieht man immer wieder. Die Lösung, um dein Ding zum laufen zu bekommen, ist einfach eine Kopie des Zeigers zu nehmen, nicht auf 0 zu prüfen und einfach nur delete zu machen, wie oben schon erwähnt.
Also so:
void do_delete(T* obj) { delete obj; } for_each(begin, end, do_delete);Besser wäre aber direkt ordentliche Speicherverwaltung. Von Boost ptr-Containern halte ich allerdings Abstand, ptr_map hat z.B. keine intuitive Semantik. Weiters verwenden die Container intern void*, was das Debugging schwerer macht (habe ich zumindest gehört, ich verwende die Dinger ja nicht.)
Ich bevorzuge vector<unique_ptr<T>> bzw vector<shared_ptr<T>>.
-
Naja, man kann sich mit etwas Fantasie schon Zusammenhänge vorstellen, wo man so etwas brauchen könnte. In den meisten dieser Fälle könnte man sich vermutlich sauberere Lösungen vorstellen, aber ich weiß ja nicht, was der TE genau vorhat.
Jedenfalls kann man das ganze mit Referenzen machen:
template <typename T> void SafeDelete(T *&ppT) { delete ppT; // delete NULL; macht nichts. ppT = NULL; } for_each(container.begin(), container.end(), SafeDelete<X>);
-
seldon schrieb:
Naja, man kann sich mit etwas Fantasie schon Zusammenhänge vorstellen, wo man so etwas brauchen könnte. In den meisten dieser Fälle könnte man sich vermutlich sauberere Lösungen vorstellen, aber ich weiß ja nicht, was der TE genau vorhat.
Jedenfalls kann man das ganze mit Referenzen machen:
template <typename T> void SafeDelete(T *&ppT) { delete ppT; // delete NULL; macht nichts. ppT = NULL; } for_each(container.begin(), container.end(), SafeDelete<X>);Danke Leute!
-
Bist du sicher, dass du die Zeiger nullen musst?
-
Wieso? Sollte das denn schlecht sein?
-
Nein, aber unnötig. Wenn du danach mit den Zeigern nichts mehr machts z.B..
-
Gast2344 schrieb:
Wieso? Sollte das denn schlecht sein?
Du übernimmst Dinge aus anderen Zusammenhängen ohne ihren Zweck zu verstehen. Es ist eine Art Cargo Cult.