0

私は中級/上級のC++プログラム、正確にはビデオゲームを作成しています。

最近、かなりの量のメモリがリークされていることに気づき、インスタンスの作成方法に何か問題があるのではないかと考えていました。

以下は要約された(しかし元々は複雑な)クラスです:

class theObject
{
 //Instance variables
 //Instance functions
};

このオブジェクト(私が保存している他のオブジェクトと一緒に、私はのすべての異なるバリエーションテンプレートの配列インデックスを持っていますtheObject。その部分は重要ではありませんが、私がそれらを保存する方法(または私の意見)は次のとおりです。

//NEWER VERSION WITH MORE INFO
void spawnTheObject()
{
 theObject* NewObj=ObjectArray[N];
 //I give the specific copy its individual parameters(such as its spawn location and few edited stats)
 NewObj->giveCustomStats(int,int,int,int);//hard-coded, not actual params
 NewObj->Spawn(float,float,float);
 myStorage.push_back(new theObject(*NewObj));
}


//OLDER VERSION
void spawnTheObject()
    {
     //create a copy of the arrayed object
     theObject* NewObj=new theObject(*ObjectArray[N]);
     //spawn the object(in this case it could be a monster), and I am spawning multiple copies of them obviously
     //then store into the storage object(currently a deque(originally a vector))
     myStorage.push_back(new theObject(*NewObj));
     //and delete the temporary one
     delete NewObj;
    }

現在、deque(最近、ベクトルの使用から変更されました)を使用していますが、メモリ使用量に違いは見られません。しかし、「コメントテスト」から、私が持っているこれらのスポーン関数がメモリリークの原因であることがわかりました。これはインスタンスを作成/生成するための間違った方法であるため、これらのオブジェクトを格納するためのより良い方法があるかどうか疑問に思いました。

tl; dr:一定量でないオブジェクトを格納するためのより良いオブジェクトとその方法を教えてください。

4

2 に答える 2

2

myStorage(メモリリークを参照すると)メモリが増加する原因となる新しいスポーンオブジェクトをクリアすることは決してないと思います。私が正しければ、myStorageは次のように宣言されます。

std::deque<theObject*> myStorage;

以下のいずれかの呼び出しを呼び出すと、オブジェクトへのポインタは削除されますが、動的に割り当てられた実際のオブジェクトは削除されません。

 myStorage.pop_back();
 myStorage.clear();

コードのもう1つの小さな問題は、関数内で不要なオブジェクトの割り当て/割り当て解除を行っていることspawnTheObject()です。

ポインタタイプでコンテナをクリーンアップする方法

myStorageの各要素を反復処理し、オブジェクトを削除してから、コンテナーをクリアする必要があります。次に例を示します。

for (std::deque<theObject*>::iterator iter=myStorage.begin();
     iter != myStorage.end(); ++iter)
{
   delete (*iter);
}
myStorage.clear();

より良い解決策:

std::dequeまたはでスマートポインタを使用するstd::vectorと、STLコンテナから要素を削除すると、ポインタが指しているオブジェクトも自動的に削除されます。

 #include <memory>

 std::deque<std::shared_ptr<theObject> > myStorage;
 myStorage.push_back(std::shared_ptr<theObject>(new *ObjectArray[N]));

 mySorage.clear();  // all memories cleared properly, no worries
于 2013-01-09T07:56:10.037 に答える
0

ゲームの終了時またはオブジェクトを破棄する必要があるときにオブジェクトを手動で削除しないmyStorageと、メモリリークが発生します。

myStorage.push_back(new theObject(*NewObj));

ストレージにプッシュされているオブジェクトはユーザーによって割り当てられているため、オブジェクトを非表示にする必要がある場合は、ユーザーがオブジェクトを破棄する必要があります。

また、中間オブジェクトの必要性もわかりNewObjません。メモリリークではありませんが、不要なパフォーマンスコスト、1つの割り当て/割り当て解除+1つのコピーです。

Foreverが述べたように、最善の策は、std::unique_ptrまたはstd::shared_ptr(c ++ 11の場合のみ)のいずれかでスマートポインターの使用を開始することです。

于 2013-01-09T06:38:35.427 に答える