Test, ob Objekt im Heap oder Stack ist
-
Hallo,
kann man in C++ auf irgendeine Weise feststellen, ob ein Objekt, von dem man nur einen Zeiger besitzt, sich im Heap oder im Stack befindet?
Das sollte dann etwa eine Funktion wie die folgende sein:bool ObjectInHeap (void *obj) { falls obj im Heap return true; falls obj in Stack return false; }
-
Ne (der C++-Standard kennt afaik "Heap" und "Stack" nicht), und wofür brauchst du das?
-
kann man in C++ auf irgendeine Weise feststellen, ob ein Objekt, von dem man nur einen Zeiger besitzt, sich im Heap oder im Stack befindet?
Nein, das geht nicht (kurze Antwort).
Die lange Antwort findest Du in einem der Effective C++ Bücher von Scott Meyers.Ein Workaround:
Ein Ansatz ist es eine Factory Methode anzubieten, die das Objekt auf dem Heap erzeugt. Dabei ist der Konstruktor privat. Dann ist garantiert, dass das Objekt eben auf dem Heap liegt.Simon
-
Das funktioniert nicht. Meistens deuten auch Versuche, das herauszufinden, auf fragwürdiges Design hin (z.B. falls ein Objekt im Heap ist, soll es automatisch freigegeben werden).
-
Wäre es denn sicher, den new-Operator in der Klasse zu überladen, von der ich wissen will, ob sie auf dem Heap liegt. zu überladen und die Addresse abzuspeichern. Nun hat man eine Liste aller auf dem Heap liegenden Objekte; die anderen sind dann auf dem Stack.(?)
-
Wozu brauchst du das überhaupt? Gut möglich, dass es bessere Ansätze gibt.
-
für die Implementierung einer sicheren Zeigerklasse ähnlich wie boost::shared_ptr-Klasse. Falls ein Objekt auf dem Stack abgelegt wird, soll der Mechanismus der automatischen Destruktion automatisch ausgeschaltet werden; zusätzlich soll - zumindest in der Debug Version - bei der automatischen Destruktion geprüft werden, ob noch weitere Zeiger auf das Objekt existieren.
Ein Workaround wäre ja, dies im Konstruktor als Parameter mitanzugeben; es scheint mir allerdings ein wenig umständlich. Außerdem funktionieren Standardkopierkonstruktoren dann nicht mehr so gut.
-
Genau das dachte ich mir.

Smart-Pointer brauchen aber keinen solchen Mechanismus, da sie ihr Objekt grundsätzlich immer auf dem Heap anlegen. Was bei
shared_ptrnoch dazukommt, ist die Referenzzählung. Es wird geschaut, wieviele andere Smart-Pointers auf ein Objekt zeigen. Der letzte gibt dann frei. Falls du was eigenes implementieren willst (wohl eher zu Übungs- und Testzwecken, Boost schlägst du nicht so schnell), würde ich dir raten, ebenfalls ausschliesslich auf dem Heap zu arbeiten. Zeiger auf Objekte auf dem Stack brauchen ja nicht "smart" zu sein.Auch
shared_ptrwird den Speicher zerschreiben, wenn du ihm ein Objekt übergibst, das auf dem Stack erstellt wurde (vom modifizierbaren Deleter mal abgesehen).P.S. "Stack" und "Heap" sind zwar geläufige Begriffe, aber nicht ganz korrekt. Ich würde eher "automatischer" und "dynamischer Speicherbereich" verwenden.
-
Noch eine Anmerkung:
Es gibt nicht nur "Stack-" und "Heapspeicher". Es gibt auch noch die Möglichkeit, dass man rohen Speicher selber verwaltet über placement new. Daher ist die optionale Übergade eines Destruktors an den Konstruktor desshared_ptreine sehr feine Sache, da man das Verhalten dann selber steuern kann, wie man es gerade benötigt. Man hat also viel mehr Möglichkeiten, als wenn du es automatisieren willst.Mach es lieber so, dass der smart pointer per Standard ein Destruktorobjekt erstellt, welches "Heapspeicher" freigibt, also per delete, und dann noch eine Möglichkeit, dass der Benutzer der Bibliothek ein eigenes Destruktorobjekt mitgeben kann.
Grüssli
-
fqt4 schrieb:
Wäre es denn sicher, den new-Operator in der Klasse zu überladen, von der ich wissen will, ob sie auf dem Heap liegt. zu überladen und die Addresse abzuspeichern. Nun hat man eine Liste aller auf dem Heap liegenden Objekte; die anderen sind dann auf dem Stack.(?)
Funktioniert nicht, da das Objekt als Teil eines anderen Objekts erst recht wieder auf dem Heap liegen könnte, ohne dass dein operator new aufgerufen wird.
Und wozu willst du überhaupt eigene smart-pointer basteln?