debug版本运行没有问题,而release版本总是报错?

下面将讲述一下我的几点经验,看看是不是其中之一:

1. 变量。

大家都知道,debug跟release在初始化变量时所做的操作是不同的,debug是将每个字节位都赋成0xcc(注1),而release的赋值近似于随机(我想是直接从内存中分配的,没有初始化过)。这样就明确了,如果你的程序中的某个变量没被初始化就被引用,就很有可能出现异常:用作控制变量将导致流程导向不一致;用作数组下标将会使程序崩溃;更加可能是造成其他变量的不准确而引起其他的错误。所以在声明变量后马上对其初始化一个默认的值是最简单有效的办法,否则项目大了你找都没地方找。代码存在错误在debug方式下可能会忽略而不被察觉到,如debug方式下数组越界也大多不会出错,在release中就暴露出来了,这个找起来就比较难了:(
还是自己多加注意吧

2. 自定义消息的消息参数。

MFC为我们提供了很好的消息机制,更增加了自定义消息,好处我就不用多说了。这也存在debug跟release的问题吗?答案是肯定的。在自定义消息的函数体声明时,时常会看到这样的写法:afx_msg LRESULT OnMessageOwn(); Debug情况下一般不会有任何问题,而当你在Release下且多线程或进程间使用了消息传递时就会导致无效句柄之类的错误。导致这个错误直接原因是消息体的参数没有添加,即应该写成:afx_msg LRESULT OnMessageOwn(WPARAM wparam, LPARAM
lparam); (注2)

3. release模式下不出错,但debug模式下报错。

这种情况下大多也是因为代码书写不正确引起的,查看MFC的源码,可以发现好多ASSERT的语句(断言),这个宏只是在debug模式下才有效,那么就清楚了,release版不报错是忽略了错误而不是没有错误,这可能存在很大的隐患,因为是Debug模式下,比较方便调试,好好的检查自己的代码,再此就不多说了。

4. ASSERT, VERIFY, TRACE..........调试宏

这种情况很容易解释。举个例子:请在VC下输入ASSERT然后选中按F12跳到宏定义的地方,这里你就能够发现Debug中ASSERT要执行AfxAssertFailedLine,而Release下的宏定义却为"#define ASSERT(f) ((void)0)"。所以注意在这些调试宏的语句不要用程序相关变量如i++写操作的语句。VERIFY是个例外,"#define VERIFY(f) ((void)(f))",即执行,这里的作用就不多追究了,有兴趣可自己研究:)。

总结:

Debug与Release不同的问题在刚开始编写代码时会经常发生,99%是因为你的代码书写错误而导致的,所以不要动不动就说系统问题或编译器问题,努力找找自己的原因才是根本。我从前就常常遇到这情况,经历过一次次的教训后我就开始注意了,现在我所写过的代码我已经好久没遇到这种问题了。下面是几个避免的方面,即使没有这种问题也应注意一下:

1. 注意变量的初始化,尤其是指针变量,数组变量的初始化(很大的情况下另作考虑了)。

2. 自定义消息及其他声明的标准写法

3. 使用调试宏时使用后最好注释掉

4. 尽量使用try - catch(...)

5. 尽量使用模块,不但表达清楚而且方便调试。

时间: 2024-10-22 15:17:06

debug版本运行没有问题,而release版本总是报错?的相关文章

【转】Debug 运行正常,Release版本不能正常运行

http://blog.csdn.net/ruifangcui7758/archive/2010/10/18/5948611.aspx引言 如果在您的开发过程中遇到了常见的错误,或许您的Release版本不能正常运行而Debug版本运行无误,那么我推荐您阅读本文:因为并非如您想象的那样,Release版本可以保证您的应用程序可以象Debug版本一样运行. 如果您在开发阶段完成之后或者在开发进行一段时间之内从来没有进行过Release版本测试,然而当您测试的时候却发现问题,那么请看我们的调试规则1

debug版本的DLL调用release版本的DLL引发的一个问题

stl的常用结构有 vector.list.map等. 今天碰到需要在不同dll间传递这些类型的参数,以void*作为转换参数. 比如 DLL2 的接口 add(void*pVoid); 1.在DLL1中调用该接口, struct st_headerTerminalRes{ st_headerTerminalRes(){id=0;} int id; int type;//restype 1=mc 2=camera int resId; int headerId;};typedef vector<

关于Code Blocks无编译器版本及VC6.0插入、打开报错

CodeBlocks运行C成功,编译C++一直报错:fatal error:stdlib.h:no such file or directory.下载重装了几次Code Blocks无编译器版本以及MINGW.看了很多教程,并不能解决问题.据说是版本对不上,于是重置电脑,安装带有编译器的版本成功运行.至于具体原因有待探究. 另VC6.0插入.打开报错,微软官方之前给出了相应插件,不过现已失效.使用百度引擎找到免费.便捷的链接并不容易.为了方便大众,现将链接附上. https://pan.baid

Android更新最新版本的SDK5.0引用v7资源报错问题

在更新完成android sdk后创建了项目,然后选择的sdk版本是android 21,系统自动创建了v7的资源项目,然后本项目引用了该v7. 可是问题来了,v7资源项目里的res资源属性报错,no found missing!!!!WTF v7也是21版本的,结果res里面生成的values-large-v14里的有个 <style name="Theme.Base.AppCompat.DialogWhenLarge" parent="Theme.Base.AppC

解决CentOS7下运行docker容器时出现的报错Error resolving syscall name...

最近在研究docker!在虚拟机centos7中运行docker经常会有: [[email protected] docker]$ docker run -it lin/centos6 /bin/bash 2016/11/08 19:38:53 Error resolving syscall name execveat: could not resolve name to syscall - ignoring syscall. 2016/11/08 19:38:53 Error resolvin

5.0以上运行正常,5.0以下报错

遇到一个变态问题,导入一个jar,5.0以上运行正常,5.0以下就报错 Error inflating class com.esri.android.map.MapView 1 1 后来发现是导入的依赖包太多了,可以通过下面的配置解决 1.在build.gradle里面加 defaultConfig { multiDexEnabled true } 1 2 3 1 2 3 2.在Application里面加 @Override protected void attachBaseContext(C

android 升级ADT22版本后,使用第三方类库项目报错:java.lang.NoClassDefFoundError:xx.xx.xx

用友盟的分享sdk遇到了这个问题:java.lang.NoClassDefFoundError:com.umeng.socialize.controller.UMServiceFactory. 产生原因:android ADT版本升级后产生的. 解决办法:①.build path-->order and export中把第三方jar包的位置上调: ②.如果第一种办法不好用,请试一试,右击项目名称-->Build path-->configure build path.. 此时会弹出类库设

程序从高版本降到2.0,数据集报错 TypedTableBase

错误  命名空间“System.Data”中不存在类型或命名空间名称“TypedTableBase”(是缺少程序集引用吗?) 解决: 该错误出现在自动生成的XXX.Designer.cs里. .NET 3.5 : public partial class T_OPERATOR_WLDataTable : global::System.Data.TypedTableBase<T_OPERATOR_WLRow> 要改成 .NET 2.0: public partial class T_OPERAT

MySQL8.0版本连接问题(解决驱动时区报错)

jdbc.properties jdbc.driverClass=com.mysql.cj.jdbc.Driver jdbc.connectionURL=jdbc:mysql://127.0.0.1:3306/myshop?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=CONVERT_TO_NULL&serverTimezone=Asia/Shanghai&useSSL=false jdbc.use