【问题标题】:valgrind (memcheck) tool didnot detect memory-leakvalgrind (memcheck) 工具未检测到内存泄漏
【发布时间】:2012-04-26 11:34:03
【问题描述】:

我用以下一段 C 代码引入了内存错误:

#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 检测到 Invalid read/write 和肯定丢失的错误,这是正确的和预期的。

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

Memcheck 检测到无效的读/写错误,但虽然所有这些错误都在一种方法中,但不一定会丢失。我可以帮助我让 memcheck 检测内存泄漏(肯定丢失)错误吗?

提前致谢, 光伏

【问题讨论】:

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

标签: c valgrind


【解决方案1】:

valgrind 如何知道您丢失了分配的内存?它可以在程序结束时看到内存没有被释放,但这是它可以为你做的一切。如果程序永远不会退出,valgrind 会认为您以后可能仍想释放它。

即使 valgrind 会检查所有变量并尝试检测没有​​人指向您分配的内存的开头:以某种修改后的形式存储地址是完全合法的;例如,到真正开始之后的字节(想想 Pascal 字符串)。所以 valgrind 无法检测你的代码是否仍然知道分配的内存。因此,即使是这种方式,valgrind 也无法帮助您。

【讨论】:

    【解决方案2】:

    要真正让 valgrind 检测到泄漏,您必须将另一个值影响到 a

    尝试添加:

    a = NULL;
    

    在你的 for() 循环之后。

    现在 valgrind 应该抱怨了!
    除非您失去对它的追踪,否则它不会告诉您您“无法挽回地失去”记忆。

    【讨论】:

    • valgrind 如何知道内存真的泄露了?
    • 好吧,如果您丢失了分配指针的 的跟踪,您无法恢复它。 Valgrind 有一个功能,它知道程序中的任何值何时都没有指向内存区域,就像垃圾收集器一样。
    • 不是真的。例如,我可以卸载指向文件的指针并稍后重新加载。我可以用一个常数对指针进行异或运算,以降低堆栈粉碎的可能性。我可以通过删除尾随的 0 来紧密打包几个指针(由于对齐,分配的指针通常在末尾有 0)。如果我使用第 0 个字节作为长度(就像 Pascal 字符串一样),我可以保留一个指向下一个字节的指针。有数千种有效情况,我的代码中没有变量等于分配的指针值,但我可以恢复原始指针并释放它。
    • ...这就是为什么在 C++ 中实现一个合理的垃圾收集器是不可能的。
    • 除此之外:添加更多代码以检测错误没有多大意义:如果我们知道在哪里添加代码,那么我们就知道问题出在哪里,所以我们可以修复它没有valgrind。 :-P
    【解决方案3】:

    我认为你的意思是

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

    最好还是放一个

    #define N 10
    

    const int N = 10;
    

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

    【讨论】:

    • 但这不会是内存错误,这是作者试图用 valgrind 检测的事情之一......
    猜你喜欢
    • 2015-02-28
    • 2012-07-16
    • 1970-01-01
    • 1970-01-01
    • 2020-05-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多