6

静的メンバー変数のメモリを解放する方法を説明できる人はいますか? 私の理解では、クラスのすべてのインスタンスが破棄された場合にのみ解放できます。この時点で私は少し無力です...

それを説明するいくつかのコード:

class ball
{
    private:
    static SDL_Surface *ball_image;
};
//FIXME: how to free static Variable?
SDL_Surface* ball::ball_image = SDL_LoadBMP("ball.bmp");
4

8 に答える 8

12

ポインター自体は、プログラムがシャットダウンするまで存在します。しかし、それが指しているのは公正なゲームです。いつでも解放できます。

メモリ リークが心配な場合は、次のような選択肢があります。

  1. 漏れさせてください。プログラムのすべてのメモリは、シャットダウン時に解放されます。ただし、メモリを解放する以上のことが必要な場合 (デストラクタを実行する場合など)、それはあまり良い考えではありません。

  2. 作成されたクラスのインスタンスの数を追跡する静的メンバー変数を用意します。メモリがゼロになるとメモリを解放し、再び 0 を超えるとメモリを再割り当てします。

  3. プログラムのシャットダウン時に実行されるある種の関数を用意し、メモリの解放を心配させます。

  4. 可能であれば、もうポインターにならないようにします。ポインターでない場合は、心配する必要はありません。

  5. スマート ポインタまたはを使用しますauto_ptr。そうすれば、ポインター自体が破棄されたときに、メモリが処理されます。

個人的には、できる場合は 4、できない場合は 5 をお勧めしますが、いくつかの選択肢があります。

于 2010-05-04T23:18:25.720 に答える
11

その音から、ポインターはまったく必要ありません。実際、これは C ライブラリのファクトリ関数から来ているため、実際には「ファースト クラス」の C++ ポインタではありません。たとえば、安全に行うことはできませんdelete

本当の問題 (ある場合) はSDL_FreeSurface、プログラムが終了する前にそれを呼び出すことです。

これには単純なラッパー クラスが必要です。

struct smart_sdl_surface {
    SDL_Surface *handle;

    explicit smart_sdl_surface( char const *name )
        : handle( SDL_LoadBMP( name ) ) {}
    ~smart_sdl_surface()
        { SDL_FreeSurface( handle ); }
};

class ball
{
    private:
    static smart_sdl_surface ball_image_wrapper;
    static SDL_Surface *& ball_image; // reference to the ptr inside wrapper
};
smart_sdl_surface ball::ball_image_wrapper( "ball.bmp" );
SDL_Surface *&ball::ball_image = ball::ball_image_wrapper.handle;

プログラムが初期化されると、コンストラクターが呼び出され、ファイルが読み取られます。プログラムが終了すると、デストラクタが呼び出され、オブジェクトが破棄されます。

于 2010-05-04T23:34:51.767 に答える
3

この場合の静的メンバ変数はポインタです。解放することはできませんが、それが指すものは解放できます。

SDL_FreeSurface(ball_image);

ball_image次に、画像がなくなったことを記録するために、0に設定することをお勧めします。

クラスのすべてのインスタンスが破棄された場合にのみ解放できます

「クラス」が意味する場合はball、いいえ。の静的メンバーは、ballのインスタンスの数に関係なく存在し続けますball。プログラムが終了する前に静的メンバーが破棄される可能性がある唯一の方法は、クラスを含む dll をアンロードするなどの (実装に依存する) ことを行う場合です。ただし、この場合、静的メンバーは単なるポインターであるため、(1) それを破棄すると、ポインターではなくポインターが破棄されるだけであり、(2) とにかくポインターを破棄する必要はなく、重要なリソースを占有しません。

于 2010-05-04T23:19:39.953 に答える
1

ヒープ割り当てメモリを指す静的メンバーが必要な場合は、メンバーをスマート ポインターにします。

于 2010-05-04T23:20:07.647 に答える
1

静的メンバーは、メンバーであるクラスのすべてのインスタンスから完全に独立して存在します。プログラムの任意の時点でポインターを削除できます。もちろん、これが意味的に意味があるかどうかは別の問題です。

于 2010-05-04T23:22:09.390 に答える
1

Jonathan M Davis の回答に同意しますが、検討できる別のオプションは、画像やその他のリソースを「ドメイン オブジェクト」から ResourceManager クラス、またはそれらの線に沿ったものに引き出すことです。

ResourceManager は、静的またはインスタンスベースのいずれかであり、アプリケーションの残りの部分で必要なリソースをロードおよび削除するロジックを提供します。

リソースを必要とするクラスは、グローバル リソース マネージャーへの参照またはポインターを保持するだけで、リソースを管理するのではなく、マネージャーからリソースを要求できます。

于 2010-05-04T23:27:48.700 に答える
0

静的メンバー変数は削除する必要はありません。クラス内にある場合は、プログラムの全期間中いつでも使用したいためです. プログラムが終了すると、オペレーティング システムは、削除されていないメモリ領域を含め、割り当てられたメモリの合計を要求します。

もちろん、どうしても削除したい場合は、それを行うための特別な静的メンバー メソッドを作成し、プログラム内の目的の時点でそのメソッドを呼び出すことができます。しかし、静的メンバー変数のセマンティックな整合性に違反し、複雑さが増し、プログラムが大きくなるにつれて問題が発生する可能性が高くなるため、誰にもお勧めしません。

于 2012-12-16T03:20:01.913 に答える
0

static variableメモリが動的に割り当てられる場所で作業する場合は、smart_pointerまたはメモリを手動でクリアする方法を使用することをお勧めします。

の静的変数のメモリをクリアしてもdestructor、次の場合には機能しません。 静的メンバーが としてmembers of the clasではなくとして存在する場合instance in each object of the class。そのため、誰かが使用して静的変数にアクセスし、::メモリを動的に割り当てたdestructor場合、オブジェクトが作成されないため、オブジェクトは表示されず、メモリは削除されません。

于 2014-10-13T10:12:06.280 に答える