1

いくつかの配列と削除が必要なリソースがあります。これらの変数の値はプログラムの存続期間を通じて保持され、単一の関数でのみ使用されるため、静的変数に自然に適合します。

void func() {
    static GLfloat arrs[4] = {1, 1, 1, 1};
    static GLUquadric* quad = gluNewQuadric(); // delete with gluDeleteQuadric(quad)
    //... other codes ... 
}

ただし、静的を使用した場合、関数の外部からこれらの変数にアクセスできないため、これらのリソースを削除するのに問題が発生します。これらのグローバルを作成することはできますが、可能であればそれを避けたいと思います。

したがって、問題は次のとおりです。

  1. arrs []はスタックまたはヒープに割り当てられていますか?それで、私はそれを削除する必要がありますか?
  2. GLUquadricの場合、明らかにコンパイラーはそれを適切に削除する方法を知りません。今のところ、美しく機能するRAIIラッパークラスを使用しましたが、さらに簡単なアプローチがあるかどうかを探しています。

valgrindはGLUquadricをリリースしないと不平を言いました、そして私がそれらをリリースするときにプログラムがとにかく終了するはずであり、これらのリソースがプログラムの終了時におそらく(?)リリースされるとしても、valgrindをサイレンシングするのではなくクリーンアップするだけだと思います。

4

7 に答える 7

2
  1. arrs []を削除する必要はありません。これは、ヒープに割り当てられていません。スタックにもありません。どこかのデータセグメントにあり、静的プログラムデータの一部であり、プロセスが完了すると消えます。

  2. ヒープ上ですが、通常は心配する必要はありません。静的初期化中にこの種のヒープを割り当てることはあまり良くありませんが、最終的に(外部リソースなどを取り除くために)デストラクタ呼び出しが必要な場合にのみバイトします。

編集済み:私はまだそのヒープオブジェクトについて心配しています。特にそれがいくつかのライブラリから来ている場合。内部で何が行われているのかわからないため、一部のハードウェアリソースなどがロックされている可能性があります。ここではスマートポインタなどでは何もできませんが、本当にこのように割り当てる必要がある場合は、割り当て解除をatexit()関数などに登録する価値があるかもしれません。または、デストラクタを使用してすべてをグローバル静的シングルトンオブジェクトに入れます。オブジェクトにデータのみが含まれていることがわかっている場合、つまりヒープについて心配する必要がない場合にのみ、心配する必要はありません。

于 2010-09-11T00:33:27.293 に答える
1

あなたの説明では、これらの統計はそれらを使用する関数の内部で宣言されていると思います。その場合、それらを削除する必要はありません。実際、必要に応じてそれらを削除することはできませんでした。静的データが利用できない場合、関数は正しく機能しないため、削除することはできません。これらは関数の存続期間よりも長持ちするため、スタック変数ではありません。

于 2010-09-11T00:33:27.807 に答える
1

自動ptrを使用します。

int myFunc()
{
    static GLfloat                   arrs[4] = {1, 1, 1, 1};
    static std::auto_ptr<GLUquadric> quad    = gluNewQuadric();

    // Do Stuff
}

静的変数は、最初の使用時に初期化されます。
その後、アプリケーションが終了すると破棄されます。スマートポインタであるため、ポインタを削除します。

1:arrs []はスタックまたはヒープに割り当てられていますか?それで、私はそれを削除する必要がありますか?

ない。
そして、あなたはそれを削除する必要はありません。
静的ストレージ期間があります。これは、メインが終了した後、他の静的ストレージ期間オブジェクトとともに破棄されるまで存続することを意味します(作成の逆の順序で)。

2:GLUquadricの場合、明らかにコンパイラーはそれを適切に削除する方法を知りません。今のところ、美しく機能するRAIIラッパークラスを使用しましたが、さらに簡単なアプローチがあるかどうかを探しています。

いいえ。できるだけシンプルにするために、標準のものを使用してください。

于 2010-09-11T00:40:55.667 に答える
1

shared_ptr「削除」機能は単純な単一パラメーター機能であるため、カスタム削除機能を備えたTR1(またはブースト)で直接使用できます。

void func()
{
    static std::tr1::shared_ptr<GLUQuadric> quad(gluNewQuadric(), gluDeleteQuadric);
    // ...
}
于 2010-09-11T10:19:51.543 に答える
0

基本的なルールは、割り当てたものだけを削除することです。で割り当てた場合はnew、でメモリを解放しますdelete。で割り当てた場合はnew[]、でメモリを解放しますdelete[]

だから

Q1。いいえ、削除しないでください。私たちはそれを決して新しくしませんでした

Q2。はい、関数が割り当てたと仮定して削除する必要があります。ただし、問題は、Quadraticを見ると、返されたポインターが1つの「Quadtric」または「Quadtricの配列」だけで新しくなったのか、それともどこかの静的変数へのポインターにすぎないのかを判断するのが難しいことです。したがって、メモリを動的に割り当てた場合はdelete、またはdelete[]それに応じて使用してください。

于 2010-09-11T03:41:18.227 に答える
0

好奇心旺盛で将来の参考資料として、これは私のRAIIテンプレートです。

template <typename T, T* constructor(), void destructor(T*)>
class Managed {
    private:
        T* value;
    public:
        Managed() {
            value = constructor();
        }
        ~Managed() {
            destructor(value);
        }
        T* operator*() {
            return value;
        }
};

そしてそれはこのように使用されます:

typedef Managed<GLUquadric, gluNewQuadric, gluDeleteQuadric> MGLUquadric;
static MGLUquadric quad = MGLUquadric();
gluSphere(*quad, 3.0f, 20, 20);
于 2010-09-11T10:06:29.223 に答える
0

Q1とQ2:やらないでください!std::auto_ptr<GLUquadricObj>専用の削除者が割り当てを解除する必要があるリソースであるため、使用できませんgluDeleteQuadric。一般に、OpenGLやGLUのような状態駆動型エンジンでは、静的なものを使用しません。静的なものは使用しないでください。ただし、OpenGLのコンテキストでは、これは特に危険です。

もう一度、真剣に:

Q1。それをしないでください。整数の静的な4要素配列を格納してもまったくメリットはありません。必要な場所でローカルに定義します。私のアドバイス:cスタイルの配列を使用せず、代わりに次のように言ってください。

const std::array<int, 4> tArray = {1, 1, 1, 1};

Q2。上記のRAIIアドバイスは良いですが、カスタム削除機能をサポートするRAIIラッパーが必要です。

std::shared_ptr<GLUquadricObj> 
 tMyQuadric(glCreateQuadric(), glDeleteQuadric);

今それを自由に使用してください、それらがスコープ外に出て、プログラムがそれを参照しないとき、それは自動的に閉じられて破壊されます。ああ、上記のカスタムRAIIラッパーも機能すると思いますが、お願いします。自分自身とフォロワーや同僚に有利に働きましょう。標準のライブラリ構造を使用してください。

于 2010-09-11T10:33:42.997 に答える