Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1737455
  • 博文数量: 347
  • 博客积分: 9328
  • 博客等级: 中将
  • 技术积分: 2680
  • 用 户 组: 普通用户
  • 注册时间: 2010-07-29 23:45
文章分类

全部博文(347)

文章存档

2016年(1)

2013年(4)

2012年(207)

2011年(85)

2010年(50)

分类: C/C++

2011-08-22 21:53:13

原文:http://hi.baidu.com/leggle/blog/item/ec0c2e5400c3ed5dd10906a7.html

呵呵,Iris来了!由于最近所做项目接近尾声,想在release下运行却发现遇此问题,遂在网上搜寻,摘录如下:


VC编写程序在debug下正常,在release下错误

可能存在的原因:

1、内存分配问题

(1)变量初始化

Release对程序的要求较Debug严格,应该对所有的变量(特别是指针和BOOL型)都先初始化再使用。

(2)数据溢出的问题

如:程序段 char buffer[4]; int num; strcpy(buffer,”abcd”);

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

(3)内存分配方式不同

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

2、用户自定义消息应该按照定义的方式去使用

对于用户自定义消息: #define WM_USERMESSAGENAME WM_USER+1

ON_MESSAGE定义: ON_MESSAGE(WM_USERMESSAGENAME, OnUserMessageName), 该宏需要两个参数,如果消息响应函数并没有参数,编译器在压栈出栈时就会出错,而DEBUG版运行时编译器会自动加一些测试代码,所以不会造成堆栈的破坏。

解决办法:1)把ON_MESSAGE 替换成ON_MESSAGE_VOID (头文件),该宏不需要参数

2)修改消息响应函数: afx_msg void OnUserMessageName(WPARAM wparam, LPARAM lparam) //一定要加参数,不管用不用得到

3、ASSERT和VERIFY

ASSERT在release版本中不会被编译,若在ASSERT中有空间分配等,就会带来错误。改为VERIFY即可。

4、内存分配

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

5、DLL的灾难

如果你的程序使用你自己的DLL时请注意:
1)不能将debug和release版的DLL混合在一起使用。debug都是debug版,release版都是release版。
2)千万不要以为静态连接库会解决问题,那只会使情况更糟糕。

6、将Project Settings中 C++/C 项目下优化选项改为 Disable(Debug)

编译器的优化可能导致许多意想不到的错误。


参考:


另附zz:

(1) 帧指针(Frame Pointer)省略(简称 FPO ):在函数调用过程中,所有调用信息(返回地址、参数)以及自动变量都是放在栈中的。若函数的声明与实现不同(参数、返回值、调用方式),就会产生错误 ————但 Debug 方式下,栈的访问通过 EBP 寄存器保存的地址实现,如果没有发生数组越界之类的错误(或是越界“不多”),函数通常能正常执行;Release 方式下,优化会省略 EBP 栈基址指针,这样通过一个全局指针访问栈就会造成返回地址错误是程序崩溃。C++ 的强类型特性能检查出大多数这样的错误,但如果用了强制类型转换,就不行了。你可以在 Release 版本中强制加入 /Oy- 编译选项来关掉帧指针省略,以确定是否此类错误。

(2) volatile 型变量:volatile 告诉编译器该变量可能被程序之外的未知方式修改(如系统、其他进程和线程)。优化程序为了使程序性能提高,常把一些变量放在寄存器中(类似于 register 关键字),而其他进程只能对该变量所在的内存进行修改,而寄存器中的值没变。如果你的程序是多线程的,或者你发现某个变量的值与预期的不符而你确信已正确 的设置了,则很可能遇到这样的问题。这种错误有时会表现为程序在最快优化出错而最小优化正常。把你认为可疑的变量加上 volatile 试试。
阅读(1442) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~