CMemoryState 结构

提供一种方便的方法来检测程序中的内存泄漏。

语法

struct CMemoryState

成员

公共构造函数

名称 描述
CMemoryState::CMemoryState 构造一个与类相似的结构来控制内存检查点。

公共方法

名称 描述
CMemoryState::Checkpoint 获取当前内存状态的快照(检查点)。
CMemoryState::Difference 计算两个 CMemoryState 类型的对象之间的差异。
CMemoryState::DumpAllObjectsSince 转储自上一个检查点以来当前分配的所有对象的摘要。
CMemoryState::DumpStatistics 输出 CMemoryState 对象的内存分配统计信息。

备注

CMemoryState 是一个结构,没有基类。

如果堆中分配了对象的内容,但当不再需要时却未将其解除分配,就会发生“内存泄漏”。 此类内存泄漏最终会导致内存不足错误。 可通过多种方式在程序中分配和解除分配内存:

  • 使用运行时库中的 malloc/ free 系列函数。

  • 使用 Windows API 内存管理函数 LocalAlloc/ LocalFreeGlobalAlloc/ GlobalFree

  • 使用 C++ newdelete 运算符。

CMemoryState 诊断仅帮助检测未使用 delete 解除分配使用 new 操作符分配的内存时导致的内存泄漏。 其他两组内存管理函数适用于非 C++ 程序,不建议将它们与同一程序中的 newdelete 混合使用。 需要跟踪内存分配的文件和行号时,还提供额外的宏 DEBUG_NEW 来替换 new 运算符。 每当正常使用 new 运算符时,都将使用 DEBUG_NEW。

与其他诊断一样,CMemoryState 诊断仅在程序的调试版本中可用。 调试版本必须定义 _DEBUG 常量。

如果怀疑程序存在内存泄漏,可以使用 CheckpointDifferenceDumpStatistics 函数来发现程序执行中两个不同点的内存状态(分配的对象)之间的差异。 此信息可用于确定函数是否正在清理它分配的所有对象。

如果仅知道分配和解除分配的不平衡发生的位置还不能提供足够的信息,则可以使用 DumpAllObjectsSince 函数转储自上次调用 Checkpoint 以来分配的所有对象。 此转储显示分配的顺序、分配对象的源文件和行(如果使用 DEBUG_NEW 进行分配),以及对象的派生、地址和大小。 DumpAllObjectsSince 还调用每个对象的 Dump 函数来提供有关其当前状态的信息。

若要详细了解如何使用 CMemoryState 和其他诊断,请参阅调试 MFC 应用程序

注意

CMemoryState 类型的对象声明和对成员函数的调用应该用 #if defined(_DEBUG)/#endif 指令括起来。 这会导致内存诊断仅包含在程序的调试版本中。

继承层次结构

CMemoryState

要求

标头: afx.h

CMemoryState::Checkpoint

获取内存的快照摘要并将其存储在此 CMemoryState 对象中。

void Checkpoint();

备注

CMemoryState 成员函数 DifferenceDumpAllObjectsSince 使用此快照数据。

示例

请参阅 CMemoryState 构造函数的示例。

CMemoryState::CMemoryState

构造一个空的 CMemoryState 对象,该对象必须由 CheckpointDifference 成员函数填充。

CMemoryState();

示例

CMemoryState msOld;
msOld.Checkpoint();
CPerson* pper1 = new CPerson();
CPerson* pper2 = new CPerson();
msOld.DumpAllObjectsSince();

CMemoryState::Difference

比较两个 CMemoryState 对象,然后将差异存储在此 CMemoryState 对象中。

BOOL Difference(
    const CMemoryState& oldState,
    const CMemoryState& newState);

参数

oldState
CMemoryState 检查点定义的初始内存状态。

newState
CMemoryState 检查点定义的新内存状态。

返回值

如果两个内存状态不同,则为非零;否则为 0。

备注

两个内存状态参数都必须调用检查点

示例

请参阅 CMemoryState 构造函数的示例。

CMemoryState::DumpAllObjectsSince

为派生自 CObject 类的类型的所有对象调用 Dump 函数,这些对象是自上次对 CMemoryState 对象进行检查点调用以来已分配(且仍在分配)的对象。

void DumpAllObjectsSince() const;

备注

使用未初始化的 CMemoryState 对象调用 DumpAllObjectsSince 时,将转储当前内存中的所有对象。

示例

请参阅 CMemoryState 构造函数的示例。

CMemoryState::DumpStatistics

从一个由 Difference 成员函数填充的 CMemoryState 对象输出简洁的内存统计信息报表。

void DumpStatistics() const;

注解

afxDump 设备上输出的报表显示以下信息:

示例报表提供有关以下内容的数字(或数量)信息:

  • 可用块

  • 正常块

  • CRT 块

  • 忽略块

  • 客户端块

  • 程序在任意时候使用的最大内存(以字节为单位)

  • 程序当前使用的总内存(以字节为单位)

可用块是 afxMemDF 设置为 delayFreeMemDF 时延迟解除分配的块数。 有关详细信息,请参阅“MFC 宏和全局”部分中的 afxMemDF

示例

以下代码应放置在 projnameApp.cpp 中。 定义以下全局变量:

static CMemoryState oldstate, newstate, diffstate;

InitInstance 函数中,添加行:

oldstate.Checkpoint();

ExitInstance 函数添加处理程序,并使用以下代码:

newstate.Checkpoint();
if (diffstate.Difference(oldstate, newstate))
{
   TRACE(_T("Memory leaked\n"));
   diffstate.DumpStatistics();
}

现可在调试模式下运行该程序,以查看 DumpStatistics 函数的输出。

另请参阅

层次结构图