Board logo

标题: 使用 DrMemory 发现内存编程错误(4) [打印本页]

作者: look_w    时间: 2018-6-18 12:41     标题: 使用 DrMemory 发现内存编程错误(4)

内存泄露内存泄露是常见的内存错误,我们可能都曾经遇到过。不过 Dr.Memory 对内存泄露的定义比较独特,在程序退出之前,Dr.Memory 把所有依然被分配的内存分为三类:
Still-reachable allocation
很多程序分配了内存之后,在其整个生命周期内都不释放。虽然这是一种泄露,但实际上多数情况下这是无害的,甚至是特意这样设计的。因此 Dr.Memory    并不认为这是一种内存泄露,而称之为”Still-reachable allocation”。
Leak
有一些内存无法再被释放,因为指向该内存的指针丢失了。比如下面这个代码:
清单 5.内存 Leak 例子代码
1
2
3
char *ptr = malloc(10);
char *ptr1 = malloc(100);
ptr=ptr1; //leak




DrMemory 称这类错误为内存泄露。因为这些内存已经没有办法被释放了。
Possible Leak
如前所述指向内存的指针被修改会被认为是一个 Leak,但并非所有的指针修改都是一个 Leak。DrMemory 利用一些经验规则(Heuristic)将以下几种指针修改列为 Possible Leak。
第一种情况:C++程序利用 new[]分配了一个数组,该数组的每个元素都是 拥有自己的析构函数的复杂数据结构。这种情况下,New 操作符为每个元素加上一个 header 用来保存数组的个数,以便 delete[]操作符知道需要调用多少个析构函数。但 new[]返回 caller 的是 header 之后的地址,这样就变成了一个 mid-allocation 指针。这可能被 Dr memory 认为是一个内存泄露。但可以使用-no_midchunk_new_ok 选项让 DrMemory 将这类错误报告为”possible leak”而非”leak”。
参考下图,理解这种情况。
图 4.mid-chunk new从堆分配器的角度来看,buffer 的起点在 A 处,但 new 返回 B,给 Object 变量赋值。从某种角度上看,指针 A 丢失了,是一个 leak,但实际上,当调用 delete []操作符时,C++运行时库会自动将 Object 指针减 4,从而指向 A 点,再进行释放。某些编译器不使用这种做法,则没有这个问题。
第二种情况,某些 C++编译器在处理多继承时,会出现 mid-chunk 指针。很抱歉,具体细节本人也不甚了解。Dr Memory 的原文如下:it includes    instances of a pointer to a class with multiple inheritance that is cast to one of the    parents: it can end up pointing to the subobject representation in the middle of the    allocation. 您可以用-no_midchunk_inheritance_ok 选项将这类“错误”报告为”possible leak” 。
还有一种可能:std::string 类把一个 char[]数组放置在分配空间中,并返回一个指针直接指向它,造成了一个 mid-allocation 指针。您可以用-no_midchunk_string_ok 选项让这类错误显示为”possible leak”。




欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) Powered by Discuz! 7.0.0