2016-07-20 3 views
2

私は自分のアプリケーションでメモリリークの問題を抱えていました。物理モジュール(これはほとんどすべてが使用しています)では、アプリケーションの速度が非常に遅くなっています。 Visual Leak Detectorを使用することで、コンストラクターとApplyGravity関数のためにリークの大部分が発生していることがわかりました。複数のメモリリーク - ベクトルとポインタ

ParticleModel::ParticleModel(Transform* transform) 
{ 
_transform = transform; 
Acceleration = XMFLOAT3(0.0f, 0.0f, -0.1f); 
mass = 10.0f; 
force = XMFLOAT3(0.0f, 0.0f, 0.0f); 
velocity = XMFLOAT3(0.0f, 0.0f, 0.0f); 
netForce = XMFLOAT3(0.0f, 0.0f, 0.0f); 
forceMag = 0.0f; 
sForce = XMFLOAT3(0.0f, 0.0f, 0.0f); 
dragFactor = 1.0f; 
gravity = -9.81f; 

_usingGravity = false; 
_useConstAcc = true; 
laminar = true; 

radius = 0.5f; 

CollisionCheck = false; 

boolsForce = true; 

move.x = 0.0f; 
move.y = 0.0f; 
move.z = 0.0f; 
moveBy = 0.0f; 
} 

私はすべての変数を_transform = transform以外にコメントアウトしました。コンストラクタからのメモリリークがまだ発生しました。また、サイドノートは、クラスのデストラクタでポインタのメモリを解放していますが、これが最適な場所かどうかはわかりません。

ParticleModel::~ParticleModel() 
{ 
    delete _transform; 
} 

ApplyGravityにおける第二のメモリリーク:

void ParticleModel::ApplyGravity() 
{ 
    _temp = XMFLOAT3(0.0f, gravity, 0.0f); 
    _forces.push_back(_temp); //_forces is a vector of XMFLOAT3s 
} 

私はリークが引き続き発生として、しかし無駄にベクトルをクリアするとプレイしました。

出力:

Leak Hash: 0x5522F309, Count: 1, Total 12 bytes 
    Call Stack (TID 1556): 
    MSVCR120D.dll!operator new() 
c:\program files (x86)\microsoft visual studio 12.0\vc\include\xmemory0 (848): DX11 Framework.exe!std::_Wrap_alloc<std::allocator<DirectX::XMFLOAT3> >::allocate() 
c:\program files (x86)\microsoft visual studio 12.0\vc\include\vector (1588): DX11 Framework.exe!std::vector<DirectX::XMFLOAT3,std::allocator<DirectX::XMFLOAT3> >::_Reallocate() + 0x17 bytes 
c:\program files (x86)\microsoft visual studio 12.0\vc\include\vector (1619): DX11 Framework.exe!std::vector<DirectX::XMFLOAT3,std::allocator<DirectX::XMFLOAT3> >::_Reserve() 
c:\program files (x86)\microsoft visual studio 12.0\vc\include\vector (1258): DX11 Framework.exe!std::vector<DirectX::XMFLOAT3,std::allocator<DirectX::XMFLOAT3> >::push_back() 
particlemodel.cpp (58): DX11 Framework.exe!ParticleModel::ApplyGravity() 
particlemodel.cpp (290): DX11 Framework.exe!ParticleModel::Update() 
gameobject.cpp (27): DX11 Framework.exe!GameObject::Update() + 0x1F bytes 
bbparticle.cpp (193): DX11 Framework.exe!BBParticle::Update() 
smokeemitter.cpp (54): DX11 Framework.exe!SmokeEmitter::Update() 
application.cpp (1254): DX11 Framework.exe!Application::Update() + 0x30 bytes 
main.cpp (67): DX11 Framework.exe!wWinMain() 
f:\dd\vctools\crt\crtw32\dllstuff\crtexe.c (466): DX11 Framework.exe!wWinMainCRTStartup() 
KERNEL32.DLL!BaseThreadInitThunk() + 0x24 bytes 
ntdll.dll!RtlUnicodeStringToInteger() + 0x253 bytes 
ntdll.dll!RtlUnicodeStringToInteger() + 0x21E bytes 
    Data: 
    00 00 00 00 C3 F5 1C 41 00 00 00 00     .......A ........ 

私が想定し発生している他のすべてのリークがParticleModelが出力に表示されているすべての場所で呼ばれることに起因するものです。例えば、ParticleModel :: Update()はApplyGravityを呼び出します。

+0

あなたは動的にParticleModelを作成していますか? 'new'ごとに' delete'がありますか? – user463035818

+0

'ParticleModel'のユーザ定義のコピーコンストラクタと代入演算子はどこにありますか? – PaulMcKenzie

答えて

3

あなたはデストラクタでポインタを削除すると言う:

ParticleModel::~ParticleModel() 
{ 
    delete _transform; 
} 

このオブジェクトが割り当てられますどこただし、コンストラクタはありません。コンストラクタに渡され、クラスメンバに設定されます。メモリリークの原因の1つは、このオブジェクトの新しいインスタンスが割り当てられ、どこにも格納されない、または新しいインスタンスParticleModelに渡されるコードパスが存在するため、破棄されないというコードパスがあることです。

これはRAII modelに違反しています。

さらに、このクラスは恐らくviolates the Rule Of Threeで、メモリリークの別の原因となる可能性があります。この動的スコープのオブジェクトが常にコンストラクタに渡されても、Rule of Threeを正しく実行しなければ、メモリリークが発生する可能性があります。余分なボーナスとして、メモリ破損の可能性があります。

メモリを割り当てているように見えるコンストラクタには何もありません。リークする可能性があります。メモリリークの原因を特定しようとするツールは必ずしも信頼できるものではなく、その出力が理解しにくいことがあります。

風が吹き荒れているところで全スピードを鍛えるのではなく、十分に確立された設計原則に従い、正しくクラスを設計し、デバッグツールを使用して問題を見つけて修正することが常に良い方法です。

の原則では、動的スコープのオブジェクトまたはあらゆる種類のリソースがコンストラクタに割り当てられ、デストラクタで破棄されなければならないと主張しています(3つのルールに従うために、代入演算子がそのプロセスを正しく処理する)。メモリリークの実際の原因を追跡できない場合は、クラスを適切に再設計することで、根底にあるバグを修正する可能性が高くなります。

0

ポインターのベクトルの場合は、明示的に削除する必要があります。このポストをチェックし、それがParticleModelでも Does vector::erase() on a vector of object pointers destroy the object itself?

..あなたを助けるかもしれない、errはそれが目的を果たすだろう...あなたは、コンストラクタをコメントアウトして、あなたは_transformを削除してみてください? :)私は問題がコンストラクタ呼び出しであると思います、詳細なコードを投稿してください。

関連する問題