多个内存泄漏 - 矢量和指针

时间:2016-07-20 10:47:58

标签: c++ debugging directx

我的应用程序一直存在内存泄漏问题,因为它在物理模块(几乎所有东西都使用)中,导致应用程序中的大量减速。通过使用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,而不是。

2 个答案:

答案 0 :(得分:3)

你说你删除了析构函数中的指针:

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

但是,构造函数不是此对象的分配位置。它被传递给构造函数,并设置为类成员。内存泄漏的一个可能原因是存在代码路径,其中此对象的新实例被分配,但不会存储在任何地方,或传递给ParticleModel的新实例,因此,永远不会得到破坏。

这违反了RAII model

此外,这个类可能是violates the Rule Of Three,这可能是内存泄漏的另一个来源。即使这个动态范围的对象总是传递给构造函数,但如果没有正确遵循Rule Of Three,仍然可能发生内存泄漏;与可能的记忆腐败配对,作为额外的奖励。

构造函数中没有任何其他内容可以分配任何内存,并且可能泄漏任何内容。试图找到内存泄漏源的工具并不总是可靠的,有时很难理解它们的输出。

最好遵循既定的设计原则,正确设计你的课程,而不是在任何风吹过的时候全速前进,并依靠调试工具来找到并解决任何导致的问题。

为了能够验证可能没有任何内存泄漏,RAII原则规定必须在构造函数中分配动态范围的对象或任何类型的任何资源,并销毁在析构函数中(赋值运算符正确处理该过程,以符合三规则)。如果您无法追踪内存泄漏的实际来源,通过正确地重新设计类,您可能最终会修复底层错误。

答案 1 :(得分:0)

如果指针向量,则必须显式删除。查看这篇文章,它可能对你有帮助.. Does vector::erase() on a vector of object pointers destroy the object itself?

同样在ParticleModel中,您注释掉了构造函数,并尝试删除_transform ...错误是否可以达到目的? :) ..我猜问题是在构造函数调用时,请发布详细代码..