it-swarm.com.de

C++ gibt statische Variablen frei

Ich möchte, dass meine Klasse einen statischen Zeiger auf einen dynamisch zugewiesenen Speicherbereich hat. Ich verstehe, wie man es initialisiert - in meinem Fall werde ich es initialisieren, wenn das erste Objekt es benötigt. Ich weiß jedoch nicht wann/wo im Code, um ihn freizugeben. Ich würde es gerne freigeben, wenn das Programm beendet wird.

Möglicherweise kann ich den Zeiger im Destruktor meiner Objekte freigeben, aber dann müsste ich eine Objektzählung beibehalten, um zu sehen, ob es sicher ist, wenn das Objekt das letzte Objekt ist, das gerade verwendet wird. 

Gibt es einen eleganteren Weg, dies zu tun? 

Lass es mich wissen, bitte.

Danke, Jbu

22
jbu

Sie haben hier zwei Lösungen:

  1. Nicht löschen löschen (Sie sind in C++, verwenden neu und löschen, oder?);). Nahezu alle Betriebssysteme werden den von der Anwendung zugewiesenen Speicher ohnehin "befreien", wenn sie fertig ist. Dies ist jedoch keine gute Lösung, die beispielsweise das Erkennen von Speicherlecks schwierig macht.
  2. Verkapsle deinen Zeiger in eine Klasse (als Member) und benutze diese Klasse als Typ deiner Statik. Auf diese Weise wissen Sie, dass der Klassendestruktor am Ende der Anwendung aufgerufen wird. Sie löschen dann einfach Ihre Daten im Destruktor und die Arbeit ist erledigt und sauber. Das ist die Macht von RAII.

Ich schlage vor, Sie machen 2, das ist eine wirklich saubere Methode.


Hier ist ein einfaches Beispiel. Anstatt dies zu tun

static Thing* things = new Thing(); // or whatever way to initialize, here or in a specific function

Sie werden das tun:

class ThingManager // or whatever name you like
{
public:
   ThingManager( Thing* thing ) : m_thing( thing ) { }//or create it here? whatever solution suits your way of creating the data

   ~ThingManager() { delete m_thing; } // THAT's the important part!

    Thing* instance() const { return m_thing; } // or whatever accessor you need, if you need one

private:
    Thing* m_thing;
};

und dann

static ManagedThing thing; // now i can access it via thing.instance() 

Wenn das Programm endet, wird die statische Variable (das ist kein Zeiger mehr) zerstört, und der Destruktor wird dazu aufgerufen.

Es wurde geschrieben, um Ihnen eine Vorstellung davon zu geben, wie Sie das schaffen können.

19
Klaim

Wirf es in einen intelligenten Zeiger. Es hat eine statische Lebensdauer und wird nach main zurückgegeben:

static std::auto_ptr<T> thePointer;

Eine weitere Option ist die Registrierung Ihrer eigenen atexit-Funktion:

// static
void YourClass::freePointer(void)
{
    delete getPointer();
}

// static
T* YourClass::getPointer(void)
{
    if (!thePointer)
    {
        thePointer = new T;
        atexit(freePointer);
    }

    return thePointer;
}

Was wird die gleiche Wirkung haben. Eine andere Option, die Sie bereits erwähnen, ist das Halten eines statischen Zählers. Beachten Sie, dass Sie das ziemlich effektiv einpacken können.

15
GManNickG

Aus Sicht des Betriebssystems hat es keinen wirklichen Sinn, Speicherplatz freizugeben, wenn Ihr Programm beendet wird. Alles, was Sie tun, ist eine langsame Beendigung. Wenn Sie Ihre Anwendung beenden, wird der gesamte Adressraum heruntergerissen, und Sie werden alles alles auf einmal freigeben. Das explizite Aufrufen von free beim Herunterfahren einer App ist nur ein Mischen von Zeigern im Heap, die trotzdem weggeworfen werden. 

Der Hauptgrund, warum wir uns so sehr bemühen, alles explizit freizugeben, besteht darin, sicherzustellen, dass wir keinen Speicher verlieren und unser Speicherfußabdruck nicht ewig wächst. 

Wenn Sie sich jedoch sicher sein können, dass dies statisch ist, dass es nur eines gibt und Sie es nicht sicher freigeben können, bis alle anderen Objekte freigegeben wurden, ist dies ein Fall, in dem es vielleicht besser ist, die Anwendung zuzulassen Kündigung kümmere dich darum.

6
John Knoeller

Sie können Ihre statische Variable als intelligenten Zeiger deklarieren. Wenn das Programm beendet ist, wird der zugewiesene Zeiger freigegeben.

2
coelhudo

ich würde einen statischen Zähler in der Klasse definieren, um die Anzahl der Objektinstanzen zu verfolgen. Wenn der Destruktor ausgeführt wird, wird der Zähler dekrementiert. Wenn der Zähler == 0 den Speicher auch freigibt ...

0
Luca Rocchi