gpt4 book ai didi

c++ - OpenCV 3.0 + Visual Studio 内存泄漏检测器 "false"正

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:48:57 31 4
gpt4 key购买 nike

我想创建启用了 Visual Studio 内存泄漏检测器的项目 (Memory Leak Detector)

它始终运行良好,通过在我的应用程序上运行大量测试然后检查报告,我可以很容易地找到内存泄漏。

但是在将 OpenCV 3.0 静态链接到我的项目后,我得到了一些误报。

例如,最令人沮丧的错误来自 StereoBMImpl::compute 方法和调用:ocl::useOpenCL()

调试后我找到了“泄漏”的来源:

TLSData<CoreTLSData>& getCoreTlsData()
{
static TLSData<CoreTLSData> *value = new TLSData<CoreTLSData>();
return *value;
}

分析这段代码后,我们知道静态对象只分配了一次,一切都应该没问题。但是现在我有一堆误报的内存泄漏报告,例如:

{1370349} normal block at 0x0E74D560, 24 bytes long.
Data: < > FF FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00
{1370348} normal block at 0x0E74D4E0, 64 bytes long.
Data: <` t > 60 D5 74 0E CD CD CD CD CD CD CD CD CD CD CD CD

现在很难在我的应用程序中找到一些真正的内存泄漏,因为有一组来自 OpenCV 的误报。我也无法运行自动内存泄漏测试,因为输出总是包含一些泄漏。

有什么方法可以消除这些“伪”错误(如果可能的话,无需更改 OpenCV 源代码)?这很烦人。

我想其他内存泄漏检测器也会报告一些类似的伪泄漏,因为 new 运算符在没有 delete 的情况下执行(对象由操作系统自动清理)。

最佳答案

我用一种相当肮脏的方式解决了这个问题,但我没有找到更好的方法。该解决方案需要修改一个 OpenCV 文件 (system.cpp)。如果您找到更好的修复方法,请发表评论。我想更多的人可能有类似的问题。

首先,我尝试使用@JamesMcNellis 解决方案(来自上面的评论)来解决问题,方法是将 block 显式标记为_IGNORE_BLOCK: new (_IGNORE_BLOCK, __FILE__, __LINE__) .解决这个问题真的是一个很好的开始。不幸的是,泄漏类包含成员,例如std::vector ,因此跟踪来自该 vector 的分配不会被暂停。

我从 crtdbg.h 开始阅读 MSDN 函数文档我找到了一种方法来暂停内存泄漏检查一段时间。可以通过使用函数清除标志 '_CRTDBG_ALLOC_MEM_DF' 来实现:_CrtSetDbgFlag .通过 MSDN 上的示例查看详细信息:_CrtSetDbgFlag documentation .这个解决方案可能有一个缺点(我知道的一个),它会暂停所有线程的内存泄漏检查。

最后,我使用 RAII 和一些宏定义创建了简单的类来管理此功能。

我对官方 3.0 源代码应用的所有更改。

位于 system.cpp 顶部的某处(包含 precomp.hpp 之后)来自 OpenCV 的文件我添加了简单的机器:

#if defined(_MSC_VER) && defined(_DEBUG)
#include <crtdbg.h>
class MEMORY_LEAKS_CHECKING_SUSPENDER
{
public:
MEMORY_LEAKS_CHECKING_SUSPENDER()
{
value = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
int new_flag = value & (~_CRTDBG_ALLOC_MEM_DF);
_CrtSetDbgFlag(new_flag);
}

~MEMORY_LEAKS_CHECKING_SUSPENDER()
{
_CrtSetDbgFlag(value);
}

private:
int value;
};

#define SUSPEND_MEMORY_LEAKS_CHECKING MEMORY_LEAKS_CHECKING_SUSPENDER suspend_memory_leaks_checking
#else
#define SUSPEND_MEMORY_LEAKS_CHECKING
#endif

每次我想暂停内存泄漏检查时,我都必须添加:PAUSE_MEMORY_LEAKS_CHECKING;它仅在 Visual Studio 调试编译中启用。内存泄漏跟踪在离开范围后自动启用(MEMORY_LEAKS_CHECKING_SUSPENDER 类的析构函数)。

目前为了暂停我的 OpenCV 内存泄漏,我在函数中添加了暂停分配:

  • getTLSContainerStorage()
  • void* TLSDataContainer::getData() const
  • TLSData<CoreTLSData>& getCoreTlsData()
  • inline TLSStorage* TLSStorage::get()

(TLSStorage 中的最后一次暂停可能固定在主 OpenCV 存储库上 - 我简要检查了存储库)

每次修改都非常简单(例如第一次泄漏):

修改前:

static TLSContainerStorage& getTLSContainerStorage()
{
static TLSContainerStorage *tlsContainerStorage = new TLSContainerStorage();
return *tlsContainerStorage;
}

修改后:

static TLSContainerStorage& getTLSContainerStorage()
{
SUSPEND_MEMORY_LEAKS_CHECKING;
static TLSContainerStorage *tlsContainerStorage = new TLSContainerStorage();
return *tlsContainerStorage;
}

如果您修改了所有这些语句并仍然观察到内存泄漏,并且您使用 OpenCV 作为单独加载的 dll,那么请确保您使用 FreeLibrary 正确卸载了此 dll。功能。原因查DLLMain OpenCV 中的函数 system.cpp文件和 cv::__termination变量用法。

关于c++ - OpenCV 3.0 + Visual Studio 内存泄漏检测器 "false"正,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32845535/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com