MFC下使用opencv出现内存泄露的解决办法

一、现象描述

在MFC程序里只要在头文件或者cpp文件定义了Mat变量,不管该Mat是否为空,在程序退出时VisualStio都会提示发生内存泄露。下面以单文档程序为例进行说明。

class CMainFrame : public CFrameWndEx

{

     private:

Mat m_Img;

};

在CMainFrame里定义Mat m_Img。按F5调试,程序退出后在输出窗口提示如下:

线程 'Win32 线程' (0x78c) 已退出,返回值为 0 (0x0)。
Detected memory leaks!
Dumping objects ->
{141} normal block at 0x004A4E80, 29 bytes long.
 Data: <     NJ  NJ     > 00 00 00 00 90 4E 4A 00 97 4E 4A 00 00 00 00 00 
{140} normal block at 0x004A4E08, 57 bytes long.
 Data: <    (        MJ > 00 00 00 00 28 00 00 00 00 00 00 00 90 4D 4A 00 
{139} normal block at 0x004A4D90, 54 bytes long.
 Data: <    (    NJ  MJ > 00 00 00 00 28 00 00 00 08 4E 4A 00 18 4D 4A 00 
{138} normal block at 0x004A4D18, 53 bytes long.
 Data: <    (    MJ  LJ > 00 00 00 00 28 00 00 00 90 4D 4A 00 98 4C 4A 00 
{137} normal block at 0x004A4C98, 61 bytes long.
 Data: <    (    MJ  LJ > 00 00 00 00 28 00 00 00 18 4D 4A 00 20 4C 4A 00 
{136} normal block at 0x004A4C20, 53 bytes long.
 Data: <    (    LJ  KJ > 00 00 00 00 28 00 00 00 98 4C 4A 00 A0 4B 4A 00 
{135} normal block at 0x004A4BA0, 61 bytes long.
 Data: <    (    LJ (KJ > 00 00 00 00 28 00 00 00 20 4C 4A 00 28 4B 4A 00 
{134} normal block at 0x004A4B28, 56 bytes long.
 Data: <    (    KJ     > 00 00 00 00 28 00 00 00 A0 4B 4A 00 00 00 00 00 
Object dump complete.
程序“[9380] TestOpencv.exe: 本机”已退出,返回值为 0 (0x0)。


值得注意的定义其它opencv数据类型,均不会提示内存泄露,比如IplImage*,Rect,Point等。


二、原因探究

        Mat作为opencv里的基本图像数据类,本身自带析构函数,所以定义一个Mat变量理论上是不会导致内存泄露的。而且即便在MainFram的析构函数里显示调用Mat的析构函数,程序退出时依然提示内存泄露。但是用其它的内存泄露检测工具,比如Vld,却无法检测出该内存泄露。所以有理由怀疑是VisualStio误报。之前在网上看过一篇文章,说是因为opencv_core.dll比mfc dll先加载导致的。

“TestOpencv.exe”: 已加载“E:\OpencvTest\Debug\TestOpencv.exe”,已加载符号。
“TestOpencv.exe”: 已加载“C:\Windows\System32\ntdll.dll”,已加载符号
“TestOpencv.exe”: 已加载“C:\Windows\System32\kernel32.dll”,已加载符号
“TestOpencv.exe”: 已加载“C:\Windows\System32\KernelBase.dll”,已加载符号
“TestOpencv.exe”: 已加载“D:\Program Files\opencv\build\x86\vc10\bin\opencv_core245d.dll”,已加载符号
“TestOpencv.exe”: 已加载“C:\Windows\System32\msvcp100d.dll”,已加载符号。
“TestOpencv.exe”: 已加载“C:\Windows\System32\msvcr100d.dll”,已加载符号。
“TestOpencv.exe”: 已加载“C:\Windows\System32\mfc100ud.dll”,已加载符号。

程序退出后在输出窗口可以看到,opencv_core245d.dll在mfc的dll之前加载。

三、解决之道

  1.(不推荐做法)将”配置属性>常规>MFC的使用“ 由“在共享 DLL 中使用 MFC”修改为“在静态库中使用 MFC”。

       这种方式是很多人采取的做法,但是我不推荐这么做,因为静态库的效率较低,而且当工程比较庞大时,调用其它使用opencv的dll时,会导致莫名其妙的崩溃。

  2.(推荐做法)采取dll延迟加载技术。


  因为mfc下内存泄露主要是由于Mat这个数据类型造成的,因此只需要延迟加载定义Mat的opencv_cored.dll即可。

3.(推荐做法)将Mat封装到dll之中,在mfc应用程序中不要出现Mat。

方法二可以解决一些比较简单mfc工程下使用opencv导致的内存泄露问题,但是如果一个大型MFC应用工程,调用了很多不同类型的dll,既有win32的dll,又有mfc的dll,而且这些dll都需要用到opencv,这时候通过方法2中的设置,可能会出现opencv_cored.dll还是在mfc dll之前加载。

在工程实践中,我发现如果将需要用到opencv实现的功能封装成dll,不管是win32的还是mfc的都行,再通过mfc应用程序进行调用,是不会提示内存泄露的。



  • 5
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
提供的源码资源涵盖了Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值