2012-04-26 65 views
2

我介绍了存储器错误的与下面的一段的C代码:的valgrind(MEMCHECK)工具因此未检测内存泄漏

#include <stdio.h> 
#include <stdlib.h> 

int main(int argc, char** argv){ 
int i; 
int *a = (int *)malloc(sizeof(int) * 10); 
if (!a) return -1; /*malloc failed*/ 
for (i = 0; i < 11; i++){ 
    a[i] = i; 
} 

for (i = 0; i < 11; i++){ 
printf("a[%d] = %d\n",i ,a[i]); 
} 
// free(a); 
return 0; 
} 

MEMCHECK检测到的错误无效的读/写和绝对丢失,这是正确的和预期的。

现在,我添加了相同的一段代码到我的应用程序的共享对象文件(的.so)。此应用程序作为服务运行,并且是守护进程。它永远不会退出。我将valgrind应用于我的应用程序,并调用了修改后的'.so'。

MEMCHECK检测无效的读取/写入错误,但不是绝对失去尽管所有这些错误是在一个method.can我得到一些帮助,使MEMCHECK检测内存泄漏(绝对丢失)错误?

由于提前, PV

+0

您是否抱怨Valgrind在仍然运行的应用程序中未检测到内存泄漏?据我所知,Valgrind在进程退出之前无法检测内存泄漏 - 换句话说,在报告错误之前,您必须停止守护进程。 – 2012-04-26 12:27:41

回答

7

如何Valgrind的知道你失去了跟踪你分配的内存?它可以在程序结束时看到内存未被释放,但这是它可以为你做的所有事情。如果程序永远不会退出,valgrind认为你可能还想在以后再释放它。

即使将Valgrind的检查所有的变量,并尝试检测,没有一个指向你分配的内存的开头:这是完全合法的存储在一些修改形式的地址;例如,超过真正的开始字节(想想Pascal字符串)。所以valgrind无法检测到你的代码是否仍然知道分配的内存。因此,即使这样,valgrind也无法帮助你。

-1

我认为你的意思是

for (i = 0; i < 10; i++) 

这将是不过最好把

#define N 10 

const int N = 10; 

在你的代码的开头,然后使用符号N而不是10

+2

但是,那么它不会是一个内存错误,这是作者试图用valgrind检测到的东西之一... – 2012-04-26 12:22:59

0

实际上使Valgrind的检测泄漏,你要影响另一价值a

尝试增加:

a = NULL; 

你对()循环之后。

现在valgrind应该抱怨!
它不会告诉你,你“无可挽回地失去了”你的记忆,除非你失去它的轨道。

+0

valgrind如何知道内存真的泄露? – Vlad 2012-04-26 13:56:39

+0

好吧,如果你忽视了alloc'ed指针的*值*,你*不能*恢复它。Valgrind具有这样的功能:它可以知道程序中的内存区域何时未被任何值指向,就像垃圾收集器一样。 – Gui13 2012-04-26 14:42:12

+0

不是真的。例如,我可以卸载指向文件的指针并稍后重新加载。我可以用一个常量来异或者指针,以便减少堆栈碎片的可能性。我可以通过删除尾随0来紧紧包装几个指针(由于对齐,分配的指针通常在末尾有0)。如果我使用长度为0的字节(像Pascal字符串那样),我可以保留一个指向下一个字节的指针。有成千上万的有效情况下,我的代码中没有一个变量等于分配的指针值,但我可以恢复原始指针并释放它。 – Vlad 2012-04-26 18:04:13