什么是`静态字符THIS_FILE [] = __FILE __;`?

时间:2012-11-07 18:35:35

标签: visual-c++ memory-leaks mfc visual-studio-debugging memory-leak-detector

static char THIS_FILE[] = __FILE__;是什么意思?

简介:它有什么作用?它来自哪里?

MFC,用于Windows的微软本机类库,有一个DEBUG_NEW宏,用于跟踪内存分配及其发生的位置(在用户代码中)。

为此,VS向导将以下代码块放入每个cpp文件中:(头文件中

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

并且调试新宏被定义为(在afx.h中):

#define DEBUG_NEW new(THIS_FILE, __LINE__)

整个机器将产生有意义的泄漏检测输出,如:

Detected memory leaks!
Dumping objects ->
f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\strcore.cpp(141) : {615} normal block at 0x04081CE0, 56 bytes long.
 Data: <¬9Í]            > AC 39 CD 5D 13 00 00 00 13 00 00 00 01 00 00 00 
c:\my\dev\path\myfile.cpp(237) : {614} normal block at 0x04087FC0, 4 bytes long.
 Data: <ð   > F0 1C 08 04 
Object dump complete.

那么,又是什么问题?

令我困惑的是THIS_FILE char数组的用途。机器没有意义。如果他们将DEBUG_NEW定义为:

#define DEBUG_NEW new(__FILE__, __LINE__)

他们可以将它放在标题中并完成它,而不是在每个文件中都有ifdef块。

那么,THIS_FILE是什么意思?

(顺便说一句,这正是MS'CRT对malloc_malloc_dbg所做的事情,其中​​调试宏在标题crtdbg.h中定义为:

#define   malloc(s)             _malloc_dbg(s, _NORMAL_BLOCK, __FILE__, __LINE__)

再说一遍,为什么在MFC DEBUG_NEW宏中以简单的方式工作(更好)时会以复杂的方式完成?


更新:哈!我最近注意到VS2005向导没有THIS_FILE的定义放入生成的cpp文件中。

调查它,似乎MS在不久前决定,它不再是必要的,因为在afxtempl.h中定义了以下内容:

#undef THIS_FILE
#define THIS_FILE __FILE__

尽管如此,我猜这个问题仍然存在,至于为什么它是必要的。 (我想当时对内存要求的回答是非常有效的。)


3 个答案:

答案 0 :(得分:8)

调试分配器将指针存储到堆块中的文件名。只需4个字节,而不是让每个分配的块也必须为文件名分配空间。

请注意,当泄漏的块由DLL分配并且在生成泄漏报告时卸载DLL时,这可能会导致调试信息丢失。

在translaton单元中,只保证字符数组THIS_FILE始终相同。不是__FILE__,这是一个文字。并且两个文字不保证具有相同的地址,即使它们具有相同的值,这意味着编译器可以为__FILE__的每次使用创建不同的文字 - 并且用尽内存。

答案 1 :(得分:0)

我相信,我可能错了,这是描述编译的exe内部的内存块。如果你要获得一个异常,你可以跟踪内存链接以查找有问题的代码,这将有所帮助,因为你知道加载了dll / exe的地址。

答案 2 :(得分:0)

__FILE__在整个文件中都是相同的,而__LINE__在每一行都发生了变化。因此,如果文件中有大量调试代码,那些没有很好地合并常量的旧编译器会有很多不必要的字符串“filename.ext”。您可以使用-fno-merge-constants之类的东西检查差异(对不起,那就是gcc CFLAG,对VS来说不确定)。大多数编译器现在默认合并常量,使得该定义不必要。