为什么Release版出错,Debug版的不出错

yjinf 2003-05-15 06:22:56
一个多文档程序,子窗口和视图是重新写的,现在Release版运行时出错,错误产生在CView的OnCreate()成功,子窗口的OnCreate()尚未返回的时候。换用别的视图就运行正常,并且我将自己写的视图中的所有函数内都注释掉,相当于一个很干净的视图类,只有成员变量和空函数,也出错。但是Debug版运行正常,不知这样的问题怎么跟踪和解决。急等
...全文
492 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
yjinf 2003-05-19
  • 打赏
  • 举报
回复
自己Up一下
yjinf 2003-05-17
  • 打赏
  • 举报
回复
我找到问题出在什么地方了,但不知道是什么原因。
我是建立了一个多文档项目,从CMDIChiledFrame和CView派生两个新类,替换掉默认的文档模板中的子窗口和视图类,我为了监控当前激活的子窗口,在子窗口中响应WM_CHILDACTIVATE消息,Release版就出错,去掉WM_CHILDACTIVATE消息响应就没问题,就是很“干净”的程序也一样,不知是什么原因,大家也可以试试。
deskzhc 2003-05-15
  • 打赏
  • 举报
回复
我也经常遇到这样的问题,试试改变C/C++的优化方式(Optimization),大多数情况下会有效的!!
yjinf 2003-05-15
  • 打赏
  • 举报
回复
多谢,我再试试
jruv 2003-05-15
  • 打赏
  • 举报
回复
精辟,那边考过来了
能不能把原地址贴一下
zxyin1 2003-05-15
  • 打赏
  • 举报
回复
up
free_card 2003-05-15
  • 打赏
  • 举报
回复
. 内存分配问题

1. 变量未初始化。下面的程序在debug中运行的很好。

thing * search(thing * something)
BOOL found;
for(int i = 0; i < whatever.GetSize(); i++)
{
if(whatever[i]->field == something->field)
{ /* found it */
found = TRUE;
break;
} /* found it */
}
if(found)
return whatever[i];
else
return NULL;
而在release中却不行,因为debug中会自动给变量初始化found=FALSE,而在release版中则不会。所以尽可能的给变量、类或结构初始化。

2. 数据溢出的问题

如:char buffer[10];
int counter;

lstrcpy(buffer, "abcdefghik");

在debug版中buffer的NULL覆盖了counter的高位,但是除非counter>16M,什么问题也没有。但是在release版中,counter可能被放在寄存器中,这样NULL就覆盖了buffer下面的空间,可能就是函数的返回地址,这将导致ACCESS ERROR。

3. DEBUG版和RELEASE版的内存分配方式是不同的 。如果你在DEBUG版中申请 ele 为 6*sizeof(DWORD)=24bytes,实际上分配给你的是32bytes(debug版以32bytes为单位分配), 而在release版,分配给你的就是24bytes(release版以8bytes为单位),所以在debug版中如果你写ele[6],可能不会有什么问题,而在release版中,就有ACCESS VIOLATE。

II. ASSERT和VERIFY

1. ASSERT在Release版本中是不会被编译的。

ASSERT宏是这样定义的

#ifdef _DEBUG
#define ASSERT(x) if( (x) == 0) report_assert_failure()
#else
#define ASSERT(x)
#endif
实际上复杂一些,但无关紧要。假如你在这些语句中加了程序中必须要有的代码
比如

ASSERT(pNewObj = new CMyClass);

pNewObj->MyFunction();

这种时候Release版本中的pNewObj不会分配到空间

所以执行到下一个语句的时候程序会报该程序执行了非法操作的错误。这时可以用VERIFY :

#ifdef _DEBUG
#define VERIFY(x) if( (x) == 0) report_assert_failure()
#else
#define VERIFY(x) (x)
#endif
这样的话,代码在release版中就可以执行了。

III. 参数问题:

自定义消息的处理函数,必须定义如下:

afx_msg LRESULT OnMyMessage(WPARAM, LPARAM);

返回值必须是HRESULT型,否则Debug会过,而Release出错

IV. 内存分配

保证数据创建和清除的统一性:如果一个DLL提供一个能够创建数据的函数,那么这个DLL同时应该提供一个函数销毁这些数据。数据的创建和清除应该在同一个层次上。

V. DLL的灾难

人们将不同版本DLL混合造成的不一致性形象的称为 “动态连接库的地狱“(DLL Hell) ,甚至微软自己也这么说http://msdn.microsoft.com/library/techart/dlldanger1.htm)。

如果你的程序使用你自己的DLL时请注意:

1. 不能将debug和release版的DLL混合在一起使用。debug都是debug版,release版都是release版。

解决办法是将debug和release的程序分别放在主程序的debug和release目录下


2. 千万不要以为静态连接库会解决问题,那只会使情况更糟糕。

VI. RELEASE板中的调试 :

1. 将ASSERT() 改为 VERIFY() 。找出定义在"#ifdef _DEBUG"中的代码,如果在RELEASE版本中需要这些代码请将他们移到定义外。查找TRACE(...)中代码,因为这些代码在RELEASE中也不被编译。 请认真检查那些在RELEASE中需要的代码是否并没有被便宜。

2. 变量的初始化所带来的不同,在不同的系统,或是在DEBUG/RELEASE版本间都存在这样的差异,所以请对变量进行初始化。

3. 是否在编译时已经有了警告?请将警告级别设置为3或4,然后保证在编译时没有警告出现.

VII. 将Project Settings" 中 "C++/C " 项目下优化选项改为Disbale(Debug)。编译器的优化可能导致许多意想不到的错误,请参http://www.pgh.net/~newcomer/debug_release.htm

1. 此外对RELEASE版本的软件也可以进行调试,请做如下改动:

在"Project Settings" 中 "C++/C " 项目下设置 "category" 为 "General" 并且将"Debug Info"设置为 "Program Database"。

在"Link"项目下选中"Generate Debug Info"检查框。

"Rebuild All"

如此做法会产生的一些限制:

无法获得在MFC DLL中的变量的值。

必须对该软件所使用的所有DLL工程都进行改动。

另:

MS BUG:MS的一份技术文档中表明,在VC5中对于DLL的"Maximize Speed"优化选项并未被完全支持,因此这将会引起内存错误并导致程序崩溃。

2. www.sysinternals.com有一个程序DebugView,用来捕捉OutputDebugString的输出,运行起来后(估计是自设为system debugger)就可以观看所有程序的OutputDebugString的输出。此后,你可以脱离VC来运行你的程序并观看调试信息。

3. 有一个叫Gimpel Lint的静态代码检查工具,据说比较好用http://www.gimpel.com 不过要化$的。

参考文献:

free_card 2003-05-15
  • 打赏
  • 举报
回复
rebuild all 试一下
lifeequation 2003-05-15
  • 打赏
  • 举报
回复
up
yjinf 2003-05-15
  • 打赏
  • 举报
回复
麻烦哪位高手给一个解决思路

16,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧