我想在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。所以,我的问题是:
感谢您的任何意见。 Jarda
编辑:正如@Hans Passant指出的那样,我已经尝试添加断点并观察断点变量,但是两者都没有工作,应用程序只返回代码0.如果我添加自己的断点并尝试观察变量,它表示找不到,如here所示。请注意,我不确定VS使用哪种C ++。Edit2:由于存在多个问题并且大多数问题已经解决,我将此标记为已解决的问题,并将其单独解决。
由于
答案 0 :(得分:0)
类构造函数和析构函数是否写好?
它似乎在技术上是正确的,但它是用'老式'C ++编写的。如果您将data
成员更改为std::vector<std::vector<float>>
,那么内存管理将全部由您处理。您不应该使用new
和delete
编写新的C ++代码。
第二次泄漏检测 - 4个字节:是什么导致这个以及如何获得更好的信息?
CRT可能需要为断点提供内存本身,因为断点需要在程序的生命周期内保持活动状态才会解除分配。
是否必须包含'测试过的';在'_CrtDumpMemoryLeaks();'?
之前结束
是的,在}
行上调用析构函数。这就是为什么还建议调用_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
,以便在调用所有自动析构函数后在程序出口处转储内存泄漏。
我是否正在使用泄漏检测?或者有更好的方法来做到这一点??
如果您使用的是MSVC,则可以使用内置工具进行操作。如果您使用其他编译器(如clang),那么它们会带有自己的内存验证工具,如果您在Linux上运行,那么您可以使用valgrind检测泄漏。但是,由于您使用的是Microsoft编译器,因此使用他们的工具是有意义的。