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. 注意变量的初始化,尤其是指针变量,数组变量的初始化(很大的情况下另作考虑了)。
2. 自定义消息及其他声明的标准写法
3. 使用调试宏时使用后最好注释掉
4. 尽量使用try - catch(...)
5. 尽量使用模块,不但表达清楚而且方便调试。
注1:
 debug版初始化成0xcc是因为0xcc在x86下是一条int 3单步中断指令,这样程序如果跑飞了遇到0xcc就会停下来,这和单片机编程时一般将没用的代码空间填入jmp 0000语句是一样地

 

 

遇到  Debug  成功但  Release  失败,显然是一件很沮丧的事,而且往往无从下手。如果你看了以上的分析,结合错误的具体表现,很快找出了错误,固然很好。但如果一时找不出,以下给出了一些在这种情况下的策略。  
            
          1.  前面已经提过,Debug  和  Release  只是一组编译选项的差别,实际上并没有什么定义能区分二者。我们可以修改  Release  版的编译选项来缩小错误范围。如上所述,可以把  Release  的选项逐个改为与之相对的  Debug  选项,如  /MD  改为  /MDd、/O1  改为  /Od,或运行时间优化改为程序大小优化。注意,一次只改一个选项,看改哪个选项时错误消失,再对应该选项相关的错误,针对性地查找。这些选项在  Project/Settings...  中都可以直接通过列表选取,通常不要手动修改。由于以上的分析已相当全面,这个方法是最有效的。  
    
          2.  在编程过程中就要时常注意测试  Release  版本,以免最后代码太多,时间又很紧。  
            
          3.  在  Debug  版中使用  /W4  警告级别,这样可以从编译器获得最大限度的错误信息,比如  if(  i  =0  )就会引起  /W4  警告。不要忽略这些警告,通常这是你程序中的  Bug  引起的。但有时  /W4  会带来很多冗余信息,如  未使用的函数参数  警告,而很多消息处理函数都会忽略某些参数。我们可以用  
              #progma  warning(disable:  4702)  //禁止  
              //...  
              #progma  warning(default:  4702)  //重新允许  
  来暂时禁止某个警告,或使用  
              #progma  warning(push,  3)  //设置警告级别为  /W3  
              //...  
              #progma  warning(pop)  //重设为  /W4  
  来暂时改变警告级别,有时你可以只在认为可疑的那一部分代码使用  /W4。  
    
          4.你也可以像  Debug  一样调试你的  Release  版,只要加入调试符号。在  Project/Settings...  中,选中  Settings  for  "Win32  Release",选中  C/C++  标签,Category  选  General,Debug  Info  选  Program  Database。再在  Link  标签  Project  options    最后加上  "/OPT:REF"  (引号不要输)。这样调试器就能使用  pdb  文件中的调试符号。但调试时你会发现断点很难设置,变量也很难找到——这些都被优化过了。不过令人庆幸的是,Call  Stack  窗口仍然工作正常,即使帧指针被优化,栈信息(特别是返回地址)仍然能找到。这对定位错误很有帮助。  
   
kugou123(酷狗)( http://www.xiaozhou.net)的文章真干净!  
    
  学习学习! 
Debug包含着许多的调试信息,生成的文件较大,也便于调试  
  Release为发布版,剔出了许多调试信息,优化过。文件较小。这样若在Debug运行正确,  
  到了Release运行错误,也便成为调试中的一件棘手的事 
Debug使用的动态连接库和Realease的不同,特别是在装了VC环境的机子上,Debug和Realease的都可以运行  
  但在没装VC环境的机子上,Debug的就不能运行了,会提示缺少动态连接库,所以,在要发布的时候,都会把程序编译一个Realease的版本再交给客户  
    
  另外,Debug版本的一般都会比Realease的空间要大~~ 
本文主要包含如下内容:  
  1.  Debug  和  Release  编译方式的本质区别  
  2.  哪些情况下  Release  版会出错  
  3.  怎样“调试”  Release  版的程序  
  --------------------------------------  
                            
    
  一、Debug  和  Release  编译方式的本质区别  
    
          Debug  通常称为调试版本,它包含调试信息,并且不作任何优化,便于程序员调试程序。Release  称为发布版本,它往往是进行了各种优化,使得程序在代码大小和运行速度上都是最优的,以便用户很好地使用。 

 

 Debug  和  Release  的真正秘密,在于一组编译选项。下面列出了分别针对二者的选项(当然除此之外还有其他一些,如/Fd  /Fo,但区别并不重要,通常他们也不会引起  Release  版错误,在此不讨论)  
            
  Debug  版本:  
    /MDd  /MLd  或  /MTd      使用  Debug  runtime  library(调试版本的运行时刻函数库)  
    /Od                                  关闭优化开关  
    /D  "_DEBUG"                  相当于  #define  _DEBUG,打开编译调试代码开关(主要针对  
                                            assert函数)  
    /ZI                                  创建  Edit  and  continue(编辑继续)数据库,这样在调试过  
                                            程中如果修改了源代码不需重新编译  
    /GZ                                  可以帮助捕获内存错误  
    /Gm                                  打开最小化重链接开关,减少链接时间  
                                              
  Release  版本:                
    /MD  /ML  或  /MT            使用发布版本的运行时刻函数库  
    /O1  或  /O2                    优化开关,使程序最小或最快  
    /D  "NDEBUG"                  关闭条件编译调试代码开关(即不编译assert函数)  
    /GF                                  合并重复的字符串,并将字符串常量放到只读内存,防止  
                                            被修改  
    
          实际上,Debug  和  Release  并没有本质的界限,他们只是一组编译选项的集合,编译器只是按照预定的选项行动。事实上,我们甚至可以修改这些选项,从而得到优化过的调试版本或是带跟踪语句的发布版本。  
            
  二、哪些情况下  Release  版会出错  
    
          有了上面的介绍,我们再来逐个对照这些选项看看  Release  版错误是怎样产生的  
            
    1.  Runtime  Library:链接哪种运行时刻函数库通常只对程序的性能产生影响。调试版本的  Runtime  Library  包含了调试信息,并采用了一些保护机制以帮助发现错误,因此性能不如发布版本。编译器提供的  Runtime  Library  通常很稳定,不会造成  Release  版错误;倒是由于  Debug  的  Runtime  Library  加强了对错误的检测,如堆内存分配,有时会出现  Debug  有错但  Release  正常的现象。应当指出的是,如果  Debug  有错,即使  Release  正常,程序肯定是有  Bug  的,只不过可能是  Release  版的某次运行没有表现出来而已。  
      
    2.  优化:这是造成错误的主要原因,因为关闭优化时源程序基本上是直接翻译的,而打开优化后编译器会作出一系列假设。这类错误主要有以下几种:  
      
          (1)  帧指针(Frame  Pointer)省略(简称  FPO  ):在函数调用过程中,所有调用信息(返回地址、参数)以及自动变量都是放在栈中的。若函数的声明与实现不同(参数、返回值、调用方式),就会产生错误————但  Debug  方式下,栈的访问通过  EBP  寄存器保存的地址实现,如果没有发生数组越界之类的错误(或是越界“不多”),函数通常能正常执行;Release  方式下,优化会省略  EBP  栈基址指针,这样通过一个全局指针访问栈就会造成返回地址错误是程序崩溃。C++  的强类型特性能检查出大多数这样的错误,但如果用了强制类型转换,就不行了。你可以在  Release  版本中强制加入  /Oy-  编译选项来关掉帧指针省略,以确定是否此类错误。此类错误通常有:  
              
            ●  MFC  消息响应函数书写错误。正确的应为  
              afx_msg  LRESULT  OnMessageOwn(WPARAM  wparam,  LPARAM  lparam);  
作者: waruqi
<script>document.write("
  
");</script>
  
 
2006-9-13 21:24   回复此发言  

3Release和Debug的区别?
              ON_MESSAGE  宏包含强制类型转换。防止这种错误的方法之一是重定义  ON_MESSAGE  宏,把下列代码加到  stdafx.h  中(在#i nclude  "afxwin.h"之后),函数原形错误时编译会报错  
              #undef  ON_MESSAGE  
              #define  ON_MESSAGE(message,  memberFxn)  /  
              {  message,  0,  0,  0,  AfxSig_lwl,  /  
              (AFX_PMSG)(AFX_PMSGW)(static_cast<  LRESULT  (AFX_MSG_CALL  /  
              CWnd::*)(WPARAM,  LPARAM)  >  (&memberFxn)  },  
                
          (2)  volatile  型变量:volatile  告诉编译器该变量可能被程序之外的未知方式修改(如系统、其他进程和线程)。优化程序为了使程序性能提高,常把一些变量放在寄存器中(类似于  register  关键字),而其他进程只能对该变量所在的内存进行修改,而寄存器中的值没变。如果你的程序是多线程的,或者你发现某个变量的值与预期的不符而你确信已正确的设置了,则很可能遇到这样的问题。这种错误有时会表现为程序在最快优化出错而最小优化正常。把你认为可疑的变量加上  volatile  试试。  
            
          (3)  变量优化:优化程序会根据变量的使用情况优化变量。例如,函数中有一个未被使用的变量,在  Debug  版中它有可能掩盖一个数组越界,而在  Release  版中,这个变量很可能被优化调,此时数组越界会破坏栈中有用的数据。当然,实际的情况会比这复杂得多。与此有关的错误有:  
            ●  非法访问,包括数组越界、指针错误等。例如  
                    void  fn(void)  
                    {  
                        int  i;  
                        i  =  1;  
                        int  a[4];  
                        {  
                            int  j;  
                            j  =  1;  
                        }  
                        a[-1]  =  1;//当然错误不会这么明显,例如下标是变量  
                        a[4]  =  1;  
                    }  
                j  虽然在数组越界时已出了作用域,但其空间并未收回,因而  i  和  j  就会掩盖越界。而  Release  版由于  i、j  并未其很大作用可能会被优化掉,从而使栈被破坏。  
    
  3.  _DEBUG  与  NDEBUG  :当定义了  _DEBUG  时,assert()  函数会被编译,而  NDEBUG  时不被编译。除此之外,VC++中还有一系列断言宏。这包括:  
    
          ANSI  C  断言                  void  assert(int  expression  );  
          C  Runtime  Lib  断言    _ASSERT(  booleanExpression  );  
                                                  _ASSERTE(  booleanExpression  );  
          MFC  断言                        ASSERT(  booleanExpression  );  
                                                  VERIFY(  booleanExpression  );  
                                                  ASSERT_VALID(  pObject  );  
                                                  ASSERT_KINDOF(  classname,  pobject  );  
          ATL  断言                        ATLASSERT(  booleanExpression  );  
          此外,TRACE()  宏的编译也受  _DEBUG  控制。  
    
  所有这些断言都只在  Debug版中才被编译,而在  Release  版中被忽略。唯一的例外是  VERIFY()  。事实上,这些宏都是调用了  assert()  函数,只不过附加了一些与库有关的调试代码。如果你在这些宏中加入了任何程序代码,而不只是布尔表达式(例如赋值、能改变变量值的函数调用  等),那么  Release  版都不会执行这些操作,从而造成错误。初学者很容易犯这类错误,查找的方法也很简单,因为这些宏都已在上面列出,只要利用  VC++  的  Find  in  Files  功能在工程所有文件中找到用这些宏的地方再一一检查即可。另外,有些高手可能还会加入  #ifdef  _DEBUG  之类的条件编译,也要注意一下。  
顺便值得一提的是  VERIFY()  宏,这个宏允许你将程序代码放在布尔表达式里。这个宏通常用来检查  Windows  API  的返回值。有些人可能为这个原因而滥用  VERIFY()  ,事实上这是危险的,因为  VERIFY()  违反了断言的思想,不能使程序代码和调试代码完全分离,最终可能会带来很多麻烦。因此,专家们建议尽量少用这个宏。  
    
  4.  /GZ  选项:这个选项会做以下这些事  
    
          (1)  初始化内存和变量。包括用  0xCC  初始化所有自动变量,0xCD  (  Cleared  Data  )  初始化堆中分配的内存(即动态分配的内存,例如  new  ),0xDD  (  Dead  Data  )  填充已被释放的堆内存(例如  delete  ),0xFD(  deFencde  Data  )  初始化受保护的内存(debug  版在动态分配内存的前后加入保护内存以防止越界访问),其中括号中的词是微软建议的助记词。这样做的好处是这些值都很大,作为指针是不可能的(而且  32  位系统中指针很少是奇数值,在有些系统中奇数的指针会产生运行时错误),作为数值也很少遇到,而且这些值也很容易辨认,因此这很有利于在  Debug  版中发现  Release  版才会遇到的错误。要特别注意的是,很多人认为编译器会用  0  来初始化变量,这是错误的(而且这样很不利于查找错误)。  
          (2)  通过函数指针调用函数时,会通过检查栈指针验证函数调用的匹配性。(防止原形不匹配)  
          (3)  函数返回前检查栈指针,确认未被修改。(防止越界访问和原形不匹配,与第二项合在一起可大致模拟帧指针省略  FPO  )  
            
          通常  /GZ  选项会造成  Debug  版出错而  Release  版正常的现象,因为  Release  版中未初始化的变量是随机的,这有可能使指针指向一个有效地址而掩盖了非法访问。  
            
  除此之外,/Gm  /GF  等选项造成错误的情况比较少,而且他们的效果显而易见,比较容易发现。  
    
   
http://blog.csdn.net/welcome_ck/archive/2004/12/29/233204.aspx  
  详细看完即可 
Debug和Release用的MFC库不同  
  Debug中含有较多调试信息,文件一般比Release大的多 
总结:  
  Release:编译选项是优化的,生成的文件小,有时代码有错误,它不报错。  
  Debug:选项多,生成的文件较大,只要Debug有错,一般是你的程序代码有错,不要埋怨是系统不行或者编译器有问题。
 
发信人: guset (坚持|孤独比拥抱实在), 信区: VisualC
标  题: debug和release的区别
发信站: 北大未名站 (2002年10月04日22:46:23 星期五), 转信

老早贴过一次,算是旧文重贴吧,很好的文章
DEBUG和RELEASE 版本差异及调试相关问题:
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版中,就有A
CCESS 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不会分配到空间
所以执行到下一个语句的时候程序会报该程序执行了非法操作的错误。这时可以用VERI
FY :
        #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提供一个能够创建数据的函数,那么这个D
LL同时应该提供一个函数销毁这些数据。数据的创建和清除应该在同一个层次上。
V.     DLL的灾难
人们将不同版本DLL混合造成的不一致性形象的称为 “动态连接库的地狱“(DLL Hell)
 ,甚至微软自己也这么说(http://msdn.microsoft.com/library/techart/dlldanger1
.htm)。
       如果你的程序使用你自己的DLL时请注意:
1.       不能将debug和release版的DLL混合在一起使用。debug都是debug版,releas
e版都是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/deb
ug_release.htm
1.         此外对RELEASE版本的软件也可以进行调试,请做如下改动:
在"Project Settings" 中 "C++/C " 项目下设置 "category" 为 "General" 并且将"D
ebug Info"设置为 "Program Database"。
在"Link"项目下选中"Generate Debug Info"检查框。
"Rebuild All"
如此做法会产生的一些限制:
无法获得在MFC DLL中的变量的值。
必须对该软件所使用的所有DLL工程都进行改动。
另:
MS BUG:MS的一份技术文档中表明,在VC5中对于DLL的"Maximize Speed"优化选项并未
被完全支持,因此这将会引起内存错误并导致程序崩溃。
2.         www.sysinternals.com有一个程序DebugView,用来捕捉OutputDebugStrin
g的输出,运行起来后(估计是自设为system debugger)就可以观看所有程序的Output
DebugString的输出。此后,你可以脱离VC来运行你的程序并观看调试信息。
3.         有一个叫Gimpel Lint的静态代码检查工具,据说比较好用。http://www.g
impel.com 不过要化$的。
参考文献:
1)         http://www.cygnus-software.com/papers/release_debugging.html
2)        http://www.pgh.net/~newcomer/debug_release.htm
对该文的评论
      fj81120 (2002-4-8 20:07:44)
bian tai
      ookaiii (2002-3-31 13:28:55)
这是一篇好文章,尽管它可有bug,不过只要能引起大家对问题的思考就是好文章 我同意
verybigbug 所说的 “1.不能将debug和release版的DLL混合在一起使用。debug都是de
bug版,release版都是release版---绝对是错误的。 其实关键是不要跨DLL进行内存分
配和释放 ” 我曾经遇到过这种情况,后来也就是把跨dll的malloc/free代码去除就没
有问题了,但是始终不知道为什么不能这样用,道理何在?有谁知道说一下啊
      verybigbug (2002-3-30 12:13:34)
有一些错误! DEBUG版和RELEASE版的内存分配方式是不同的?? 不对,在Debug版中分
配内存时会在内存的后面加上4BYTE的标志,并不是以32BYTE为单位的。 比如BYTE* p 
= malloc(10);在内存中分配为10BYTE+4BYTE,其中4BYTE的内容为FDFDFDFD 数据溢出的
问题 也不对。char buffer[10]; int a;的时候,用lstrcpy(buffer,"0123456789")是
不会 影响a的。因为内存分配是在Stack中时a在buffer的上面。 lstrcpy(buffer, "01
2345678901234567890")都不会影响a的,只会影响buffer上面的。 比如int a; char b
uffer[10];的时候就会影响a的。另外,default是以4BYTE对齐,所以 char buffer[10
]的话实际上可以用12BYTE。不过char buffer[12]的话还是用12BYTE。 当然,不能因为
这种原因就进行数据溢出操作,从程序的角度是不对的。还是养成良好的习惯。 1. 不
能将debug和release版的DLL混合在一起使用。debug都是debug版,release版都是rele
ase版 绝对是错误的。任何一个程序都将调用kernel32.dll,该DLL肯定是release版。
所以是不可能的。 其实关键是不要跨DLL进行内存分配和释放!比如,在DLL1中malloc
&new的内存在DLL2中使用是可以的, 但不要在DLL2中进行free&delete操作,必须在DL
L1中进行free&delete操作。否则2个DLL存在Debug 和Release版的区别时会有内存出错
!另外,即使都是release版有可能因为编译器的区别产生内存出错。 如果在同一DLL中
进行释放就不会有该问题。 本人的一些经验,请指教。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值