zoukankan      html  css  js  c++  java
  • #define new DEBUG_NEW

    #define new DEBUG_NEW


    在用vc时,利用AppWizard会产生如下代码:

    #ifdef _DEBUG
    #define new DEBUG_NEW
    #undef THIS_FILE
    static char THIS_FILE[] = __FILE__;
    #endif

    对于

    #define new DEBUG_NEW
    首先看msdn的解释:


    Assists in finding memory leaks. You can use DEBUG_NEW everywhere in your program that you would ordinarily use the new operator to allocate heap storage.

    In debug mode (when the _DEBUG symbol is defined), DEBUG_NEW keeps track of the filename and line number for each object that it allocates. Then, when you use the CMemoryState::DumpAllObjectsSince member function, each object allocated with DEBUG_NEW is shown with the filename and line number where it was allocated.

    To use DEBUG_NEW, insert the following directive into your source files:

    #define new DEBUG_NEW

    Once you insert this directive, the preprocessor will insert DEBUG_NEW wherever you use new, and MFC does the rest. When you compile a release version of your program, DEBUG_NEW resolves to a simple new operation, and the filename and line number information is not generated.


    再查看定义:

    #ifdef _DEBUG

    void* AFX_CDECL operator new(size_t nSize, LPCSTR lpszFileName, int nLine);
    #define DEBUG_NEW new(THIS_FILE, __LINE__)

    #else

    #define DEBUG_NEW new

    #endif

    这样就很清楚了,当在debug模式下时,我们分配内存时的new被替换成DEBUG_NEW,而这个DEBUG_NEW不仅要传入内存块的大小,还要传入源文件名和行号,这就有个好处,即当发生内存泄漏时,我们可以在调试模式下定位到该问题代码处。若删掉该句,就不能进行定位了。而在release版本下的new就是简单的new,并不会传入文件名和行号。

    因此,我们在开发代码阶段,保留上述代码是值得的。


    #define new DEBUG_NEW
    当进行对象转储时,用 DEBUG_NEW 分配的每个对象均将显示被分配到的文件和行号,使您可以查明内存泄漏源。


    MFC 框架的“Debug”版本自动使用 DEBUG_NEW,但代码不自动使用它。如果希望利用 DEBUG_NEW 的好处,则必须显式使用 DEBUG_NEW 或 #define new,如上所示。 

    情况1:

    #ifdef _DEBUG
    virtual void AssertValid() const;                                       //assert(断言)valid(有效的,正确的)
    virtual void Dump(CDumpContext& dc) const;            //存储上下文
    #endif

    这两个函数是调试用的,第一个函数检查可用性,即是否有效
    第二个函数如果未更改的话,最终调用的是Cwnd::Dump();
    输出窗口类名,标题名等一系列信息(在输出窗口中)


    #ifdef _DEBUG
    #endif
    这是条件编译,即如果有#define _DEBUG这两个函数会编译,否则忽略,
    当你用debug生成时(相对于release)开发环境则自动的加上这个宏定义,这两个函数有效。

    情况2:


    #ifdef _DEBUG                                                                // 判断是否定义_DEBUG
    #undef THIS_FILE                                                           // 取消THIS_FILE的定义
    static char THIS_FILE[]=__FILE__;                             // 定义THIS_FILE指向文件名
    #define new DEBUG_NEW                                         // 定义调试new宏,取代new关键字
    #endif // 结束


    如果定义了_DEBUG,表示在调试状态下编译,因此相应修改了两个符号的定义
    THIS_FILE是一个char数组全局变量,字符串值为当前文件的全路径,这样在Debug版本中当程序出错时出错处理代码可用这个变量告诉你是哪个文件中的代码有问题。
    定义 _DEBUG后,由于定义了_DEBUG,编译器确定这是一个调试,编译#ifdef _DEBUG和#endif之间的代码。#undef 表示清除当前定义的宏,使得THIS_FILE无定义。

    __FILE__ 是编译器能识别的事先定义的ANSI C 的6个宏之一。#define new DEBUG_NEW
    DEBUG_NEW定位内存泄露并且跟踪文件名.
    ////////////////////////////////////////////////////////////////////////

    情况3:

    #ifdef _DEBUG //如果是debug状态
    #undef THIS_FILE //清除THIS_FILE
    static char THIS_FILE[]=__FILE__; //定义THIS_FILE为__FILE__(这是当前文件全路径名字)
    #define new DEBUG_NEW //定义new为DEBUG_NEW(这个可以检测到内 //存泄露之类的问题,其实就是可以使用crt开头的那几个调试函数)
    #endif

    ANSI C 的6个宏:6个分别是
    __DATE__
    __FILE__
    __LINE__
    __STDC__
    __TIME__
    __TIMESTAMP__
    编译C++程序时,编译器自动定义了一个预处理器名字__cplusplus(代表C++程序),自动定义名字__STDC__(代表C程序),__LINE__记录文件已经被编译的行数__FILE__包含正在被编译的文件的名字,另外两个预定义名字分别包含当前被编译文件的编译时间__TIME__ 和日期__DATE__。

  • 相关阅读:
    使用tcmalloc编译启动时宕机
    使用tcmalloc编译出现undefined reference to `sem_init'
    使用AddressSanitizer做内存分析(一)——入门篇
    VIM-美化你的标签栏
    Entity Framework Code First (六)存储过程
    Entity Framework Code First (五)Fluent API
    Entity Framework Code First (四)Fluent API
    Entity Framework Code First (三)Data Annotations
    Entity Framework Code First (二)Custom Conventions
    Entity Framework Code First (一)Conventions
  • 原文地址:https://www.cnblogs.com/tianlangshu/p/1989492.html
Copyright © 2011-2022 走看看