一般程序在Debug版能够运行,在Release版就不能运行,啥原因?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一般程序在Debug版能够运行,在Release版就不能运行,啥原因?相关的知识,希望对你有一定的参考价值。
上次调试一个程序的时候,发现使用Debug版,程序就能正常稳定的运行,而Release版就会出现内存泄露的问题,请问这样的问题怎么样解决?是什么地方出错了?
内存泄漏吧,因为debug版本有自己的内存管理所以比较容易掩盖错误,用boundChecker查查吧 参考技术A 你也可以用Visual Leak Detector 这个软件检测内存泄漏,比较专业的。OpenCV与Debug和Release模式
1.Release和Debug的区别
Release版称为发行版,Debug版称为调试版。
Debug中可以单步执行、跟踪等功能,但生成的可执行文件比较大,代码运行速度较慢。Release版运行速度较快,可执行文件较小,但在其编译条件下无法执行调试功能。
Release的exe文件链接的是标准的MFC DLL(Use MFC in a shared or static dll)。这些DLL在安装Windows的时候已经配置,所以这些程序能够在没有安装Visual C++的机器上运行。而Debug版本的exe链接了调试版本的MFC DLL文件,在没有安装Visual C++的机器上不能运行,因为缺相应的DLL,除非选择use static dll when link。
Debug 和 Release 并没有本质的区别,他们只是VC预定义提供的两组编译选项的集合,编译器只是按照预定的选项行动。如果我们愿意,我们完全可以把Debug和Release的行为完全颠倒过来。当然也可以提供其他的模式,例如自己定义一组编译选项,然后命名为MY_ABC等。习惯上,我们仍然更愿意使用VC已经定义好的名称。
Debug版本包括调试信息,所以要比Release版本大很多(可能大数百K至数M)。至于是否需要DLL支持,主要看你采用的编译选项。如果是基于ATL的,则Debug和Release版本对DLL的要求差不多。如果采用的编译选项为使用MFC动态库,则需要MFC42D.DLL等库支持,而Release版本需要MFC42.DLL支持。Release不对源代码进行调试,不考虑MFC的诊断宏,使用的是MFC Release库,编译时对应用程序的速度进行优化,而Debug则正好相反,它允许对源代码进行调试,可以定义和使用MFC的 诊断宏,采用MFC Debug库,对速度没有优化。
既然Debug和Release仅仅是编译选项的不同,那么为什么要区分Debug和Release版本呢?
Debug和Release,在我看来主要是针对其面向的目标不同的而进行区分的。Debug通常称为调试版本,通过一系列编译选项的配合,编译的结果通常包含调试信息,而且不做任何优化,以为开发人员提供强大的应用程序调试能力。而Release通常称为发布版本,是为用户使用的,一般客户不允许在发布版本上进行调试。所以不保存调试信息,同时,它往往进行了各种优化,以期达到代码最小和速度最优。为用户的使用提供便利。
2.Opencv在Release和Debug下配置的区别
上文已经说明Release和Debug的区别,所以Opencv在Debug和Release不同环境下都需要进行对应的配置的。
另外我们需要注意,Opencv并不是Windows下标准库,所以它的DLL文件在安装Windows的时候并不会随之配置。也就是说Release和Debug环境下,Opencv库都有对应的Lib和DLL文件,我们在对应模式下都需要配置。并且在发行程序exe之后,随之的DLL文件也需要放置在同一文件夹中,否则程序会报错找不到对应的DLL文件。
永久配置结果:
3. 直接运行利用debug和release生成的exe
按照下面链接配置好opencv两种版本以后,建立新的项目,在 项目》属性》C/C++》代码生成中将运行库改为MT,然后利用release调试,release文件夹下生成的exe文件则可以直接双击运行。同理如果想直接双击运行debug文件夹下的exe文件,则将下图中的配置选为debug,然后将运行库选择为MTd即可。可以看到运行库不止这MT和MTd两个选项,这两个选项叫做静态编译。而剩下的连个选项MD和MDd叫做动态编译。
关于运行库的选项:
- 静态编译:debug状态下:MTd release状态下:MT
- 动态编译:debug状态下:MDd release状态下:MD
即区别debug或release的标志则是有无小写字母 d ,有则为debug,无则为release。那么静态编译和动态编译的又是什么呢?下面介绍。
4. 静态编译和动态编译
动态编译的生成的可执行文件的exe小,但是运行需要系统环境具有相关的dll和lib文件,就是动态调用系统相关的文件才能运行;静态编译生成的可执行文件exe大,但是运行的时候不依赖于系统环境所依赖的dll和lib等环境问题,在编译的时候已经这些dll相关文件编译进了exe文件,所以exe文件较大。所以需要自己创建的工程需要在别的电脑上运行,考虑到稳定性,同时对执行文件的大小没有要求的话还是尽量选择静态编译。
- 静态编译将导出声明和实现都放在lib中。编译后所有代码都嵌入到宿主程序。
- 静态编译的优点是编写出来的程序不需要调用DLL和载入函数,直接可以当成程序的一部分来使用。
- 静态编译的缺点也是显而易见的,使用静态编译的程序体积会比动态编译大,原因是函数的实现被嵌入为程序代码的一部分。
优缺点:所以动态编译的优点一方面是缩小了执行文件本身的体积,另一方面是加快了编译速度,节省了系统资源。缺点一是哪怕是很简单的程序,只用到了链接库中的一两条命令,也需要附带一个相对庞大的链接库;二是如果其他计算机上没有安装对应的运行库,则用动态编译的可执行文件就不能运行。静态编译就是编译器在编译可执行文件的时候,将可执行文件需要调用的对应动态链接库(.so)中的部分提取出来,链接到可执行文件中去,使可执行文件在运行的时候不依赖于动态链接库。所以其优缺点与动态编译的可执行文件正好互补。
5. OpenCV && VS静态编译和动态编译
MinGW编译器目前仅能编译OpenCV2.x.x版本,OpenCV3.x.x并不支持MinGW编译器。最重要的是,OpenCV使用的Intel的IPP库是没有MinGW版本的,最直观的差别就是,使用OpenCV开发的实时图像处理程序在处理速度上,VC版本要比MinGW版本快至少一倍。所以在windos平台上使用OpenCV,最好还用微软自家的编译器。
OpenCV官方默认使用动态链接库的形式发布,平时写OpenCV程序用于学习和研究就算了,当程序需要发布时,尤其是程序需要拷到没有OpenCV环境的机器上运行时,一堆的动态链接库弄得好烦,而且OpenCV3.1官方发布版本默认不包含vc10(也就是vs2010的编译器)的库,只好重新尝试编译。关于opencv支持那哪个vs的编译器,可以打开自己的opencv包:
可以看到opencv2.4.13版本支持的编译器有vc11和vc12,分别对应的VS版本为 visual Studio 2012 和 visual Studio 2013.
vc10, vc11, vc12 分别表示VS2010, VS2012, VS2013的Visual Studio使用的编译器版本,根据自己的VS版本来填写正确的编译器版本号。
编译前,需要提前下载并安装好Cmake和VS2010,并下载好OpenCV3.1的源代码。
想在没有opencv和vs的电脑上运行 VS编译好的exe文件,则需要利用release模式(考虑到其他电脑没有VS)下静态编译(考虑到其他电脑不存在opencv的动态依赖库,依赖性小方便,就是生成的exe大些,可选)或动态编译(将对应需要的dll拷贝到exe的执行目录下,这种虽然文件多,但是易操作,也可选)。选哪种都行具体看自己的项目。
具体过程可参考;OpenCV3.1 VS2010静态编译和动态编译 和 [opencv]OpenCV项目的动态编译和静态编译
6. 补充: .dll文件和lib文件
1)Dll(Dynamic Link Library
我的环境windows10 + Visual Studio 2013 + opencv2.4.13
步骤:
1.打开项目配置页->c/c++->代码生成->运行库,设置成多线程调试DLL(/MD)(release版的动态编译程序选择MD,这一步是为了添加程序运行需要的运行库)
2.利用VS编译生成exe,然后把对应的dll库拷贝到exe的文件夹下面。将此文件夹作为一个整体发送到其他电脑。(具体需要拷贝哪些dll库可以使用visual studio的dependents查看,方法如下)
使用dependents查看exe所需要的dll库:
- 开始->所有程序->Microsoft Visual Studio 2010 ->Visual Studio Tools->VS2013 x86本机工具命令提示
- 跳转到exe所在根目录下,输入dumpbin /dependents main.exe,就会有如图所示结果。
我们需要添加三个opencvdll库,除此还需额外添加opencv_ffmpeg247.dll,不然总提示读取视频失败。下面的几个DLL文件在上面步骤一修改运行库时就已经添加了。
步骤:
1、把工程调成Release模式。
2、右键项目->属性打开项目属性页面,首先在配置属性->常规页面,如果是MFC程序,则在“MFC的使用”选择“在静态库中使用MFC”。然后在配置属性->C/C++ ->代码生成页面,“运行库”里面选“多线程(/MT)”。
3、然后生成重新解决方案,生成了之后会在项目的Release文件夹下面看到一个exe文件和一个pdb文件(注意:这不是用静态库生成的)。
4、打开opencv2-4-13的安装目录,在“安装路径opencv\\build\\x86\\vc12\\bin目录下将所有的Release版本(不带字母d的dll)的动态库文件拷贝到Release文件夹里面,跟exe文件放在一起。这样生成的exe程序就可以在其他电脑上面运行了。
参考于:
http://blog.csdn.net/FX677588/article/details/72622011
https://www.zhihu.com/question/24400428 知乎上的关于opencv debug和release版本的永久配置
http://blog.csdn.net/leo2007608/article/details/38963947 CSDNS上的opencv debug和release版本的永久配置
http://www.cnblogs.com/xujianqing/p/5356559.html 关于opencv转换debug和release版本出现的问题。
如何生成能在没有安装opencv库及vs2010环境的电脑上运行的exe文件
关于debug和release的问题,个人觉得还是分别建两个新项目属性OpencvDebug和OpencvRelease比较方便。
以上是关于一般程序在Debug版能够运行,在Release版就不能运行,啥原因?的主要内容,如果未能解决你的问题,请参考以下文章
在C++中,Debug版本能顺利运行,但Release版本有时却不能运行,为啥?
移动端ionic cordova 打包debug调试版release发布版