VC++中Debug调试版本和Release发行版本的区别

正在调一个程序,在Debug模式下运行没有问题,在Release下碰到 Expression: (unsigned)(c + 1) <= 256的错误,后来找了些资料如下:


写代码过程中,发现 Debug 下运行正常,Release 下就会出现问题,百思不得其解,而Release 下又无法进行调试,于是只能采用printf方式逐步定位到问题所在处,才发现原来是给定的一个数组未初始化,导致后面处理异常。网上查找了些资料,在这 罗列汇总下,做为备忘~

I.    内存分配问题   

     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"优化选项并未被完全支持,因此这将会引起内存错误并导致程序崩溃。 

转自:

http://blog.csdn.net/stellar0/article/details/8762946

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值