【发布时间】:2015-12-27 00:37:16
【问题描述】:
我想创建启用了 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 的情况下执行(对象由操作系统自动清理)。
【问题讨论】:
-
这不是误报,这是实际的内存泄漏。
-
@JamesMcNellis 我同意,但不幸的是它不会在 OpenCv 中得到修复。我报告了这个问题(github.com/Itseez/opencv/issues/5452),但它被标记为 wontfix(它是“静态初始化/销毁顺序失败”的解决方法)。任何想法如何处理这个问题?
-
如果修改 OpenCv 是一个选项,那么您可以更改
getCoreTlsData()函数以将块类型显式传递给调试运算符 new,例如new (_IGNORE_BLOCK, __FILE__, __LINE__) TlsData<CoreTLSData>()。或者(但更丑陋),您可以通过delete &getCoreTlsData();在执行泄漏检查之前自己释放块。但这需要谨慎的时间安排:您必须确保在 OpenCv 使用它之后执行此操作。 -
@JamesMcNellis 非常感谢,它不像您建议的那么简单,但它向我展示了一种暂停内存泄漏检查的方法。我在下面描述了我的解决方案。
标签: c++ visual-c++ memory-leaks opencv3.0