C ++ Visual Studio - 解释内存泄漏检测的简单示例

时间:2015-01-09 14:31:23

标签: c++ memory-leaks visual-studio-2013

我想在C ++中开始使用VS Memory Leak检测。由于我更习惯Java,这里有一个简单的例子我有问题。我想测试简单的漏洞类。部首:

#pragma once
class Tested{
public:
    Tested();
    ~Tested();

    const int N = 10;
    const int PARS = 3;

    float* getDataLine(int n);

private:
    float** data;
};

Cpp文件:

#include "stdafx.h"
#include "Tested.h"
using namespace std;

Tested::Tested() {
    data = new float*[N];
    for (int i = 0; i < N; i++){
        data[i] = new float[PARS];
    }
}

float* Tested::getDataLine(int n){
    return data[n];
}

Tested::~Tested() {
    for (int i = 0; i < N; i++){
        delete[] data[i];
    }
    delete[] data;
}

stdafx.h中

#pragma once
#include "targetver.h"
#include "CppUnitTest.h"

// http://msdn.microsoft.com/en-us/library/e5ewb1h3(v=vs.71).aspx
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#ifdef _DEBUG
    #ifndef DBG_NEW
        #define DBG_NEW new ( _NORMAL_BLOCK , __FILE__ , __LINE__ )
        #define new DBG_NEW
    #endif
#endif  // _DEBUG

最后是测试类:

#include "stdafx.h"
#include "Tested.h"
using namespace Microsoft::VisualStudio::CppUnitTestFramework;

namespace Test{
    TEST_CLASS(MemoryLeakTest){
    public:
        TEST_METHOD(AllDataAccess){
            //_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
            //_CrtSetBreakAlloc(147);
            {
                Tested t;
                float* line = t.getDataLine(0);
                line[0] = 10;
            }
            _CrtDumpMemoryLeaks();
        }
    };
}

现在,如果我注释掉了删除[]数据的行;&#39;,泄漏检测报告很好并且指向数据**初始化的行:

Detected memory leaks!
Dumping objects ->
c:\users\j\dropbox\workspace\visualstudio\memoryleaktest\neurontest\tested.cpp(7) : {148} normal block at 0x06B09D68, 40 bytes long.
 Data: <        `       > D0 9D B0 06 18 9E B0 06 60 9E B0 06 A8 9E B0 06 
{147} normal block at 0x06B09BA8, 4 bytes long.
 Data: <    > F0 D9 16 0F 
Object dump complete.

但如果我使用&#39;删除[]数据;&#39; (如图所示),检测输出显示如下:

Detected memory leaks!
Dumping objects ->
{147} normal block at 0x060A72F0, 4 bytes long.
 Data: <    > F0 D9 C2 0F 
Object dump complete.

如果我取消注释&#39; TEST_METHOD()&#39;对于147位置的断点。调试通常会在没有进一步信息的情况下退出(log here)。

我正在使用Visual Studio 2013和Visual C ++ Native Unit Test Project。所以,我的问题是:

  • 是否将类构造函数和析构函数写为OK ??
  • 第二次泄漏检测 - 4个字节:是什么导致这个以及如何获得更好的信息?那就是:为什么断点不起作用?
  • 是否必须包含“测试t”的块;&#39;结束之前&#39; _CrtDumpMemoryLeaks();&#39;?
  • 我使用泄漏检测吗?或者有更好的方法来做到这一点??

感谢您的任何意见。 Jarda

编辑:正如@Hans Passant指出的那样,我已经尝试添加断点并观察断点变量,但是两者都没有工作,应用程序只返回代码0.如果我添加自己的断点并尝试观察变量,它表示找不到,如here所示。请注意,我不确定VS使用哪种C ++。

Edit2:由于存在多个问题并且大多数问题已经解决,我将此标记为已解决的问题,并将其单独解决。

由于

1 个答案:

答案 0 :(得分:0)

  

类构造函数和析构函数是否写好?

它似乎在技术上是正确的,但它是用'老式'C ++编写的。如果您将data成员更改为std::vector<std::vector<float>>,那么内存管理将全部由您处理。您不应该使用newdelete编写新的C ++代码。

  

第二次泄漏检测 - 4个字节:是什么导致这个以及如何获得更好的信息?

CRT可能需要为断点提供内存本身,因为断点需要在程序的生命周期内保持活动状态才会解除分配。

  

是否必须包含'测试过的';在'_CrtDumpMemoryLeaks();'?

之前结束

是的,在}行上调用析构函数。这就是为什么还建议调用_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);,以便在调用所有自动析构函数后在程序出口处转储内存泄漏。

  

我是否正在使用泄漏检测?或者有更好的方法来做到这一点??

如果您使用的是MSVC,则可以使用内置工具进行操作。如果您使用其他编译器(如clang),那么它们会带有自己的内存验证工具,如果您在Linux上运行,那么您可以使用valgrind检测泄漏。但是,由于您使用的是Microsoft编译器,因此使用他们的工具是有意义的。