我们有几个单元测试使用 Win32 _CrtMemCheckpoint
/_CrtMemDifference
方法来检测被测代码中的内存泄漏。在 x64 机器 (Windows 7) 上,其中一些测试报告内存泄漏,而在 x86(32 位)机器上没有报告。在这些 x64 机器上,使用 VS2008 或 VS2012 编译以下代码并使用 Boost 1.52.0,结果是“检测到内存泄漏!”:
#include <boost/filesystem.hpp>
#include <crtdbg.h>
int main(int argc, char **argv)
{
_CrtMemState state1, state2, state3;
_CrtMemCheckpoint(&state1);
{
boost::filesystem::path remoteDirPath("c:/");
}
_CrtMemCheckpoint(&state2);
int res = _CrtMemDifference( &state3, &state1, &state2);
if (res != 0)
{
_CrtDumpMemoryLeaks();
std::cout << "Memory leak detected!";
}
}
这实际上是 boost::filesystem::path 中的内存泄漏吗?我猜这是一些图书馆初始化,因为
int main(int argc, char **argv)
{
{
boost::filesystem::path initDummy("c:/");
}
_CrtMemState state1, state2, state3;
_CrtMemCheckpoint(&state1);
{
boost::filesystem::path remoteDirPath("c:/");
}
_CrtMemCheckpoint(&state2);
int res = _CrtMemDifference( &state3, &state1, &state2);
if (res != 0)
{
_CrtDumpMemoryLeaks();
std::cout << "Memory leak detected!";
}
}
不输出“检测到内存泄漏!”。
我的问题是:单元测试如何避免此类问题?在开始测试之前初始化这样一个变量是解决方案吗?使用其他代码时,我是否需要做更多这样的事情?还是进行此类测试通常不是一个好主意?
谢谢你的想法!
最佳答案
由于你的第二个代码示例,我会说 boost::filesystem::path 正在初始化一些静态内部状态(它一直分配到你的程序结束)。
How can I avoid such problems with unit tests?
创建一个在获取第一个内存检查点之前执行的测试初始化方法。
理想情况下,您应该能够自定义分配和解除分配以进行跟踪(覆盖新建/删除、添加您的自定义分配器等),但这更加困难并且可能不允许这样做,具体取决于您使用的库。
Is initializing such a variable before starting the test a solution?
这是一种解决方法。不是很优雅,但最终,它会告诉你你想知道的。
Will I have to do many more such things when using other code?
取决于您使用的库以及它们的灵 active 。如果您正在测试您完全拥有的代码,您应该考虑在内部使用分配器类型(您可以自定义以跟踪分配的 std::allocator)、自定义新建和删除或编写一些您可以为其提供多个实现的分配 API。
您还可以使用不显式依赖 _CrtMem* Windows API 的测试代码(boost::test 库有一个运行时参数来检测内存泄漏,因此您不必自己实际实现它,但我不了解它在 Win64 中的幕后工作。
关于c++ - boost::filesystem::path 导致内存差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17447519/