c++ - boost::filesystem::path 导致内存差异

标签 c++ unit-testing memory-leaks

我们有几个单元测试使用 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/

相关文章:

c++ - 如何将这些 c 代码行转换为 c++

c++ - 为什么我不能将 std::from_chars 的结果分配给 std::tie?

c# - 这可以用最小起订量来模拟吗?

ios - 如果遇到 fatal error ,如何停止 Xcode iOS 单元测试?

java - 什么是堆栈溢出错误?

internet-explorer - ExtJS 和臭名昭著的内存泄漏

c++ - (Im) 使用可变参数模板完美转发

python - 测试是否引发了 ValidationError

jquery - 使用 AngularJS/jQuery 分离 DOM 树

c++ - 在 C++ 中对两个字符数组进行异或运算