即使释放了所有堆块,Valgrind也会出错

时间:2010-09-28 14:25:46

标签: c valgrind

我最近养成了通过valgrind运行所有程序来检查内存泄漏的习惯,但是大部分结果对我来说都有点神秘。

对于我的最新动作,valgrind -v给了我:

All heap blocks were freed -- no leaks are possible

这意味着我的程序涵盖内存泄漏,对吗?

那么这个错误意味着什么?我的程序没有正确读取某些内存块吗?

ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 14 from 9)

1 errors in context 1 of 1:
Invalid read of size 4
   at 0x804885B: findPos (in /home/a.out)
   by 0xADD918: start_thread (pthread_create.c:301)
   by 0xA26CCD: clone (clone.S:133)
 Address 0x4a27108 is 0 bytes after a block of size 40 alloc'd
   at 0x4005BDC: malloc (vg_replace_malloc.c:195)
   by 0x804892F: readInput (in /home/a.out)
   by 0xADD918: start_thread (pthread_create.c:301)
   by 0xA26CCD: clone (clone.S:133)

used_suppression:     14 dl-hack3-cond-1

此外,这里所谓的“抑制”错误是什么?

4 个答案:

答案 0 :(得分:19)

这似乎很明显......但值得指出的是"no leaks are possible"消息并不意味着您的程序无法泄漏;它只是意味着它在测试的配置中没有泄漏。

如果我使用没有命令行参数的valgrind运行以下命令,它会通知我没有泄漏是可能的。但如果我提供命令行参数,它确实会泄漏。

int main( int argc, char* argv[] )
{
   if ( argc > 1 )
      malloc( 5 );
   printf( "Enter any command line arg to cause a leak\n" );
}

答案 1 :(得分:12)

  1. 是的,你被大大覆盖,不要 认为valgrind很容易错过 用户代码泄漏
  2. 你的错误意味着你可能 索引数组时出现+1错误 变量。 valgrind的线条 告诉你应该准确,所以你 如果您使用-g
  3. 编译所有代码,应该很容易找到
  4. 抑制错误通常来自 系统库,有时会出现小的泄漏或不可检测的事情,比如线程的状态变量。您的手册页应列出默认使用的抑制文件

答案 2 :(得分:1)

检查内存泄漏是使用valgrind的一个原因,但我想说更好的理由是在代码中发现更严重的错误,例如使用无效的数组下标或取消引用未初始化的指针或指向释放内存的指针

如果valgrind告诉你运行valgrind时运行的代码路径没有导致内存泄漏,那就好了,但是不要让它忽略更严重错误的报告,例如你看到的那个这里。

正如其他人所建议的那样,在使用调试信息(-g)进行编译后重新运行valgrind将是一个很好的下一步。

答案 3 :(得分:0)

如果您遇到以下错误:- “大小为4的读取无效”

您是否要先释放内存然后转到下一个参数? 我也收到错误消息,因为在链接列表中,我先释放内存,然后再转到下一个元素。 以下是我遇到错误的代码段-

void free_memory(Llist **head_ref)
{
    Llist *current=NULL;

    current=*head_ref;
    while(*head_ref != NULL)
    {
        current=*head_ref;
        free(current);
        current=NULL;
        (*head_ref)=(*head_ref)->next;
    }
}

下面的更改是我的代码段-

void free_memory(Llist **head_ref)
{
    Llist *current=NULL;
    current=*head_ref;
    while(*head_ref != NULL)
    {
        current=*head_ref;
        (*head_ref)=(*head_ref)->next;
        free(current);
        current=NULL;
     }
 }