Debug和Release区别

VC下Debug和Release区别

最近勾勒代码过程中,发现 Debug 下运行正常化,Release
下便见面冒出问题,让我百思念不得其解,而Release
下同时力不从心进展调剂,于是只能使printf方式逐渐稳定及问题所在处,才意识原来是加的一个数组未初始化,导致后面处理非常。网上搜索了若干资料,在及时
罗列汇总下,做也备忘~ 
一、Debug 和 Release 的区别 
        Debug
通常称为调试版本,它蕴含调试信息,并且不作外优化,便于程序员调试程序。Release
称为发布版,它数是展开了各种优化,使得程序在代码大小以及周转速度高达都是极美的,以便用户非常好地运。 
     Debug 和 Release 的真正分,在于一组编译选项。 
Debug 版本   
参数       含义   
/MDd /MLd 或 /MTd 使用 Debug runtime
library(调试版本的运转时刻函数库)   
/Od 关闭优化开关   
/D “_DEBUG” 相当于 #define
_DEBUG,打开编译调试代码开关(主要针对assert函数)   
/ZI   
缔造 Edit and
continue(编辑继续)数据库,这样于调试过程中一旦改动了来自代码不需再次编译   
GZ 可以辅助捕获内存错误  

   
Release 版本 参数含义   
/MD /ML 或 /MT 使用发布版的运作时刻函数库   
/O1 或 /O2 优化开关,使程序太小或者极抢   
/D “NDEBUG” 关闭条件编译调试代码开关(即非编译assert函数)   
/GF 合并重复的字符串,并以字符串常量放到只念内存,防止被改  

Debug 和 Release
并无本质之尽头,他们只有是一样组编译选项之聚集,编译器只是按预约的选料项行动。 
   
连锁经历: 转自http://dev.csdn.net/article/17/17068.shtm 

  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.
留意变量的初始化,尤其是凭针变量,数组变量的初始化(很充分之情状下任何发考虑了)。 

  1. 自打定义信息以及其他声明的正儿八经写法 
  2. 利用调试宏时使用后极好注释掉 
  3. 尽量以try – catch(…) 
  4. 尽可能使模块,不但表达清楚而方便调试。 
    注1: 
    debug版初始化成0xcc是坐0xcc于x86下是千篇一律漫漫int
    3才步中断指令,这样程序一旦走飞了遇到0xcc就会告一段落下来,这与单片机编程时相似用尚未因此之代码空间填入jmp
    0000报告句是一律地转贴于:计算机二级考试_考试大【责编:drfcy 纠错】

[VC]DEBUG和RELEASE2007年08月26日 星期日 下午 04:33    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”优化增选并未为全支持,因此这将见面招内存错误并造成程序崩溃。   
    
   2.    http://www.sysinternals.com/发出
一个序DebugView,用来捕捉OutputDebugString的输出,运行起来后(估计是自设为system   
debugger)就得望所有程序的OutputDebugString的输出。此后,你可脱离VC来运转而的次第并见到调试信息。   
    
   3.    有一个为Gimpel   
Lint的静态代码检查工具,据说比较好用http://www.gimpel.com/   
不过若是化$的。

相关文章