对象转储转译
本主题适用于:
版本 |
Visual Basic |
C# |
F# |
C++ |
Web Developer |
---|---|---|---|---|---|
学习版 |
仅限本机 |
||||
专业版、高级专业版和旗舰版 |
仅限本机 |
查看此对象转储的更详细信息:
{5} strcore.cpp(80) : non-object block at $00A7521A, 9 bytes long
{4} strcore.cpp(80) : non-object block at $00A751F8, 5 bytes long
{3} strcore.cpp(80) : non-object block at $00A751D6, 6 bytes long
{2} a CPerson at $51A4
Last Name: Smith
First Name: Alan
Phone #: 581-0215
{1} strcore.cpp(80) : non-object block at $00A7516E, 25 bytes long
生成该转储的程序只有两个显式分配,一个在框架上,另一个在堆上:
// Do your memory allocations and deallocations.
CString s("This is a frame variable");
// The next object is a heap object.
CPerson* p = new CPerson( "Smith", "Alan", "581-0215" );
CPerson 构造函数取三个参数(指向 char 的指针),用于初始化 CString 成员变量。 在内存转储中,可以看到 CPerson 对象以及三个非对象块(3、4 和 5)。 它们保存 CString 成员变量的字符,并且在调用 CPerson 对象析构函数时不会被删除。
块号 2 是 CPerson 对象本身。 $51A4 表示块地址,其后是对象内容,该内容在 DumpAllObjectsSince 调用 CPerson::Dump 时由后者输出。
可以因为块号 1 的序号和大小(与框架 CString 变量中的字符数匹配)而猜测其与 CString 框架变量相关联。 框架上分配的变量在框架超出范围后自动释放。
框架变量
一般情况下,您不必担心与框架变量关联的堆对象,因为它们在框架变量超出范围后被自动释放。 为避免内存诊断转储混乱,应将对 Checkpoint 的调用定位在框架变量的范围以外。 例如,在前面的分配代码周围放置范围括号,如下所示:
oldMemState.Checkpoint();
{
// Do your memory allocations and deallocations ...
CString s("This is a frame variable");
// The next object is a heap object.
CPerson* p = new CPerson( "Smith", "Alan", "581-0215" );
}
newMemState.Checkpoint();
放置了范围括号后,该示例的内存转储如下所示:
Dumping objects ->
{5} strcore.cpp(80) : non-object block at $00A7521A, 9 bytes long
{4} strcore.cpp(80) : non-object block at $00A751F8, 5 bytes long
{3} strcore.cpp(80) : non-object block at $00A751D6, 6 bytes long
{2} a CPerson at $51A4
Last Name: Smith
First Name: Alan
Phone #: 581-0215
非对象分配
请注意,一些分配是对象分配(如 CPerson),另外一些则是非对象分配。" “非对象分配”是用于非 CObject 派生的对象的分配,或者基元 C 类型的分配(如 char、int 或 long)。 如果 CObject 派生的类分配额外的空间(例如用于内部缓冲区),则那些对象将既显示对象分配,也显示非对象分配。
防止内存泄漏
注意,在上面的代码中,与 CString 框架变量关联的内存块已自动释放,因而不作为内存泄漏显示。 与范围规则关联的自动释放负责处理与框架变量关联的大多数内存泄漏。
但对于在堆中分配的对象,则必须显式删除对象以防止内存泄漏。 若要清理上个示例中的最后一个内存泄漏,请删除堆中分配的 CPerson 对象,如下所示:
{
// Do your memory allocations and deallocations.
CString s("This is a frame variable");
// The next object is a heap object.
CPerson* p = new CPerson( "Smith", "Alan", "581-0215" );
delete p;
}