To 楼主 ,我在另外一个类似的贴子作了回答
http://expert.csdn.net/Expert/topic/2955/2955693.xml?temp=.3361933
内容大致如下:
happyparrot(快乐鹦鹉) 说的是现象,是正确的;除此之外,我还想补充一点。
不知楼主有没有想过,为什么要用到 release 的版本呢?我想很重要的原因为是为了优化程序上,
使之运行得更快,编出来的 exe 更小。但问题就出在里----优化 ( Optimization )
下面的几点可能在优化时会引起编译错误 ( Compiler bugs ):
1.Storage Allocator Issues
2.Uninitialized Local Variables
3.Bounds Errors
4.Mixed DLLs
5.Run-Time Type Information (RTTI)
6.Linkage Errors
下面的几点可能在优化会引起链接错误 ( Linkage Errors ):
1.Linkage Types
2.Parameter counts
优化过程出现的编译错误
1.Aliasing bugs
2.const and volatile
3.ASSERT and VERIFY
4.memmove and memcpy
5.DLL Hell
Q: 那么,在 release 里出了问题怎么办呢?
A: 简单的来说,请去掉最优化 ( Optimization ),在 Visual C++ 里这样设置
Project->Settings...选择 C/C++ , 在 Category 选择 Optimizations ,然后在
Optimizationss 下接框里选择 Disable (Debug)。在程序中要注意上面提到的可能产生错误的地方
,还要小心使用 pragma 宏。
在网上看了好几篇关于 debut/release ( 英文 )文章,它们还有代码片断举例说明,我没一一
试过,但我想应该是正确的,人都快看昏了。
----------------------------
为什么我的程序debug版本运行没有问题,而release版本总是报错?
楼主zhuzhengzhou(特雷士)2003-09-22 19:46:47 在 VC/MFC / 基础类 提问
每次关闭程序后都要弹出类似以下3个应用程序错误
"0x77e74a1d"指令引用的" 0x6bc4b4ca"内存。该内存不能为" written"。
要终止程序,请单击“确定”
要调试程序,请单击“取消”
这是哪里出了问题?
问题点数:99、回复次数:17
Top
1 楼Onega(www.fruitfruit.com)回复于 2003-09-22 20:07:00 得分 5估计是指针越界了
在debug mode,内存分配时多分配几个字节,可能你写到那段内存了,所以debug mode没有异常,在
release mode有。检查一下与指针有关的地方
2 楼wuliangge2001(就这么回事儿)回复于 2003-09-22 20:14:52 得分 5
对,有可能。我以前也遇到过这种情况,就是指针出的问题。
3 楼haoguozhong(郝国忠)回复于 2003-09-22 20:20:10 得分 5
对,以应该是指针的问题。
4 楼lmtz007yan(忽隐忽现)回复于 2003-09-22 21:34:58 得分 5
搂主,我曾经遇到的问题恰恰与你相反!
我是Debug有问题,Release正常!
我仅仅知道Debug版本包含本机调试信息,所以个头要Release比大。
但是经过这几天对你问题的分析,坚决拥护Onega()朋友的观点!
“在debug mode,内存分配时多分配几个字节,可能你写到那段内存了,所以debug mode没有异常,在
release mode有”!
祝你进步!
5 楼fanqing(火影忍者+28%(准备学习进程/线程))回复于 2003-09-22 21:51:23 得分 5
1。编译器会在Release中进行优化,可能引起程序无法执行。
2。一些宏在Release中不会执行(在测试版本中可以运行),可能引起程序无法执行。
6 楼alienmaster(小白)回复于 2003-09-22 21:53:28 得分 5
在debug模式,释放的内存会被自动置0,在release模式就不会,
所以有些问题在debug模式下不会暴露出来,你可以从这方面想想.
7 楼lanfanghelanfanghe(眉飞色舞)回复于 2003-09-22 21:56:35 得分 20
以前有个帖子,说是在release版本实质上是产生了一个结构异常(CStructException),VC++为了使
release版本代码精简,并未将此转化成为C++异常(CATCH只能捕捉C++异常)
Project settings settings for win32 release 在在c/c++页,project
options 找到/gx将。gx改为/eha
以上好象是这样,是以前的帖子上看到的。
8 楼DDsoft163()回复于 2003-09-22 22:50:41 得分 5
看看是不是CString,如果在release 版本里需要初始化
9 楼jiangsheng(蒋晟.Net[MVP])回复于 2003-09-23 13:10:17 得分 20
变量的初始化
Debug方式下,变量的初值和Release的不同
内存的分配
Debug方式下,变量的分配会额外分配一定的空间以检测访问是否越界
消息的处理
Debug方式下,一些异常会被自动捕获,例如调用函数指针,但是错误判断了函数类型(例如自定义消息
的处理忘记声明参数)
14 楼zhuzhengzhou(特雷士)回复于 2003-09-24 09:55:22 得分 0
奇了怪了,我按照"lanfanghelanfanghe(眉飞色舞) "所说的试着做了一遍,提示有两个警告:
Command line warning D4002 : ignoring unknown option '/eha'
StdAfx.cpp
Compiling...
Command line warning D4002 : ignoring unknown option '/eha'
再运行程序的时候,问题解决了
我再把那个/eha选项删除了,也没有问题。
16 楼davidyj(秋天里的一棵树)回复于 2003-09-24 10:03:34 得分 20
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. 尽量使用模块,不但表达清楚而且方便调试。