0

私は Visual Studio 2008 を使用しており、OpenGL ウィンドウを開発しています。スケルトンを作成するためのクラスをいくつか作成しました。1 つはジョイント用、もう 1 つはスキン用、もう 1 つはボディ用 (複数のジョイントとスキンのホルダー)、もう 1 つはスケル/スキン ファイルを読み取るためです。

各クラス内で、ほとんどのデータにポインターを使用しています。そのほとんどは = new int[XX] を使用して宣言されています。delete[XX] を使用してポインタを削除する各クラスのデストラクタがあります。

GLUT 表示関数内で、本体を宣言し、ファイルを開いて描画し、表示の最後で本体を削除します。しかし、プログラムのどこかにまだメモリ リークがあります。時間が経つにつれて、メモリ使用量が一定の割合で増加し続けます。これは、削除されていないものとして解釈しています。

Body クラスを削除していないだけの glut display 関数の何かなのか、それとも何か他のものなのか、私にはわかりません。Visual Studio 2008 でメモリ リーク検出の手順を実行しましたが、リークは報告されませんが、正しく機能しているかどうかは 100% 確信が持てません。私はC++に堪能ではないので、見落としているものがあるかもしれません。誰かがそれを見ることができますか?

メインから:

void display(void){
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    Body *body = new Body();
    body->readSkel("C:\\skel2.skel");
    body->drawBody();
    body = new Body();
    body->readSkel("C:\\skel1.skel");
    body->drawBody();
    glutSwapBuffers();  
    body->~Body();
    delete body;
}

本文から:

Body::Body(){
    skelFile = string();
    skinFile = string();
    totalJoints = 0;
    joints = new Joint[25];
    skin = new Skin;
}

Body::~Body(){
    delete[25] joints;
    delete skin; 
}
4

4 に答える 4

5

このコードでは:

Body *body = new Body();
body->readSkel("C:\\skel2.skel");
body->drawBody();
body = new Body();

Body最初のものを削除しないため、リークしています。

この:

body->~Body();
delete body;

ただ奇妙です。そのようなデストラクタを明示的に呼び出す必要はありません - がdeleteデストラクタの呼び出しを処理します。

このコード:

delete[25] joints;

も奇妙です。正しい形式は次のとおりです。

delete [] joints;

非標準の構文を使用しているため、25無視されます。詳細については、この質問を参照してください。

于 2010-04-08T17:20:27.593 に答える
3

本物のプログラマーは、どの言語でもFortran Java を書くことができます! Java では (事実上) すべてを動的に割り当てる必要がありますが、C++ では必要ありません。

他の誰もそれを (少なくとも直接的に) 指摘していないので、display動的割り当てを使用する理由はまったくないようです。次のようなことをしてください:

void display(void){
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    Body body;
    body.readSkel("C:\\skel2.skel");
    body.drawBody();

    Body body2;
    body2.readSkel("C:\\skel1.skel");
    body2.drawBody();
    glutSwapBuffers();  
}

既存のスケルトン データをクリアする場合readSkelは、 を定義する必要はありませんがbody2、それを知らなくても、これは物事を安全に保つための簡単な方法です。

同様に、 Body の定義では、動的割り当てを必要とすることも何もしていないようです。

class Body { 
    std::string skelFile;
    std::string skinFile;
    int totalJoints;
    Skin skin;
    Joint joints[25];
public:
    Body() : totalJoints(0) {}
};

またはさらに良い:

class Body { 
    std::string skelFile;
    std::string skinFile;
    Skin skin;
    std::vector<Joint> joints;
public:
   // presumably other stuff goes here...but you don't need a ctor or dtor.
};

これにより、何かが漏れる可能性がほとんどなくなります (少なくともコードのこれらの部分では -- スキンやジョイント クラスを見ていないため、それらが何をしているのか推測するのは困難です...

于 2010-04-08T19:42:41.937 に答える
1

小さなコードを貼り付けると役に立ちますが、私は次のようにします。

構文を再確認してください。int*foo= new int [size]; delete [] foo;

デストラクタが空のステートメントであっても、親がダイナミックメモリを使用するすべての子クラスにデストラクタも含まれていることを確認してください。

于 2010-04-08T17:11:14.343 に答える
0

ヨッヘン・カルムバッハはあなたの友達です。

于 2010-04-08T17:35:56.790 に答える