web-dev-qa-db-ja.com

C ++の静的変数の解放

私のクラスには、動的に割り当てられたメモリ領域への静的ポインタが必要です。私はそれを初期化する方法を理解しています-私の場合、最初のオブジェクトがそれを必要とするときに初期化します。しかし、それを解放するためのコードのいつ/どこでそれがわからない。プログラムの終了時に解放したいのですが。

オブジェクトのデストラクタでポインタを解放できるかもしれませんが、オブジェクトが最後に使用されているときに解放しても安全かどうかを確認するために、オブジェクト数を維持する必要があります。

これを行うよりエレガントな方法はありますか?

私にお知らせください。

ありがとう、jbu

25
jbu

ここには2つの解決策があります。

  1. Do n't delete delete it(C++を使用しているので、newとdeleteを使用しますよね?;))今日のほとんどすべてのOSは、アプリケーションが終了すると、アプリケーションによって割り当てられたメモリを「解放」します。しかし、それは良い解決策ではありません。たとえば、メモリリークを検出するのが困難になります。
  2. ポインタをクラスに(メンバーとして)カプセル化し、このクラスを静的型として使用します。そうすれば、アプリケーションの最後にクラスデストラクタが呼び出されることがわかります。次に、デストラクタでデータを削除するだけで、作業は完了し、クリーンになります。それがRAIIの力です。

2を実行することをお勧めします。これは、非常にクリーンな方法です。


これは簡単な例です。これを行う代わりに

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

あなたはそれをします:

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;
};

その後

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

プログラムが終了すると、静的変数(ポインターではなくなります)が破棄され、そのデストラクターが呼び出されます。

それはあなたにそれをどのように行うことができるかについての考えをあなたに与えるためだけに書かれています。

19
Klaim

スマートポインターに入れます。静的な有効期間があり、mainが戻った後に破棄されます:

static std::auto_ptr<T> thePointer;

もう1つのオプションは、独自のatexit関数を登録することです。

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

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

    return thePointer;
}

同じ効果があります。あなたがすでに述べた別のオプションは、静的なカウンターを維持することです。実際にはかなり効果的にまとめることができます。

16
GManNickG

OSの観点から見ると、プログラムが終了するときにメモリを解放することには意味がありません。遅い終了だけです。アプリケーションの終了により、アドレス空間全体が破壊され、解放されますすべてヒープに一度に割り当てます。アプリのシャットダウン時に明示的にfreeを呼び出すと、ヒープ内のポインターがシャッフルされ、とにかく捨てられます。

すべてを明示的に解放するために一生懸命努力する主な理由は、メモリリークが発生せず、メモリフットプリントが永久に増大しないことを確認するためです。

しかし、これが静的であり、1つしか存在せず、他のすべてのオブジェクトが解放されるまで安全に解放できないことが確実である場合、これは、アプリケーションを許可するだけの方が良い場合です。終了はあなたのためにそれを世話します。

7
John Knoeller

静的変数をスマートポインターとして宣言すると、プログラムが終了すると、割り当てられたポインターが解放されます。

2
coelhudo

デストラクタが実行されるときにオブジェクトインスタンスカウントを追跡するためにクラスに静的カウンターを定義し、カウンターをデクリメントします。counter== 0の場合もメモリを解放します。

0
Luca Rocchi