【问题标题】:Valgrind legitimate "possibly lost" bytes exampleValgrind 合法的“可能丢失”字节示例
【发布时间】:2012-07-31 11:19:34
【问题描述】:

我看到 valgrind 将内存泄漏分类为:

  • 肯定输了
  • 间接丢失
  • 可能丢失
  • 仍然可以访问
  • 抑制

我刚刚修复了“可能丢失”是主要问题的泄漏。

documentation says:“可能丢失意味着您的程序正在泄漏内存,除非您使用可能导致它们指向中间的指针执行异常操作分配的块;有关一些可能的原因,请参阅用户手册"

我可以知道一个“用指针做不寻常的事情,可能导致它们指向已分配块的中间”的例子吗?

我的意思是一个可以忽略“可能丢失”的示例,尽管它是由 valgrind 报告的。一个示例,其中使用指针使 valgrind 抱怨,但同时以这种方式使用指针在某种程度上是合法的

谢谢

【问题讨论】:

    标签: c++ c valgrind


    【解决方案1】:

    文档中的一些示例是具有自己分配器的不同库,并且返回的内存不是直接由底层操作系统分配器 (malloc/sbrk) 返回的指针,而是偏移后的指针。例如,考虑一个分配器,它获得了一些额外的内存并存储了元信息(可能是垃圾收集器的类型信息......)。分配和解除分配的过程类似于:

    void* allocate( size_t size ) {
       metainfo_t *m = (metainfo_t*) malloc( size + sizeof(metainfo) );
       m->data = some_value;
       return (void*)(m+1);          // [1]
    }
    void deallocate( void* p ) {
       metainfo_t *m = ((metainfo_t*)p) - 1;
       // use data
    }
    void * memory = allocate(10);
    

    当 valgrind 跟踪内存时,它会记住 malloc 返回的原始指针,并且该指针不会存储在程序的任何位置。但这并不意味着内存已经泄漏,它只意味着指针在程序中不能直接使用。特别是memory 仍然持有返回的指针,并且可以调用deallocate 来释放它,但是valgrind 在程序中的任何位置都看不到原始返回的指针(char*)memory - sizeof(metadata_t) 并发出警告。

    【讨论】:

      【解决方案2】:
      char *p = malloc(100);
      if (p != 0)
      {
          p += 50;
          /* at this point, no pointer points to the start of the allocated memory */
          /* however, it is still accessible */
          for (int i = -50; i != 50; i++)
              p[i] = 1;
          free (p - 50);
      }
      

      【讨论】:

        【解决方案3】:
        char *p = malloc(100);
        if (p != 0)
        {
            p += 50;
            /* at this point, no pointer points to the start of the allocated memory */
            /* however, it is still accessible */
            for (int i = -50; i != 50; i++)
                p[i] = 1;
            free (p - 50);
        }
        

        因为它看起来很有趣,所以我确实运行了代码并对其进行了 valgrind。结果如下。

        yjaeyong@carbon:~$ valgrind test
        ==14735== Memcheck, a memory error detector
        ==14735== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
        ==14735== Using Valgrind-3.6.1-Debian and LibVEX; rerun with -h for copyright info
        ==14735== Command: test
        ==14735== 
        ==14735== 
        ==14735== HEAP SUMMARY:
        ==14735==     in use at exit: 0 bytes in 0 blocks
        ==14735==   total heap usage: 32 allocs, 32 frees, 2,017 bytes allocated
        ==14735== 
        ==14735== All heap blocks were freed -- no leaks are possible
        ==14735== 
        ==14735== For counts of detected and suppressed errors, rerun with: -v
        ==14735== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 11 from 6)
        

        它说不可能有泄漏。我错过了什么吗?

        【讨论】:

        • 请将 cmets 作为 cmets,而不是作为答案。 StackOverflow 会通知 cmet 的用户他们的答案,但不会(也不应该)通知用户也回答相同问题的其他用户。也就是说……
        • ...代码最终释放了内存,因此 valgrind 看不到它。我的意思是,如果程序在到达free 之前退出(或者根本没有释放),并且p 保持设置状态,那么 valgrind 将认为分配的内存可能会丢失。在测试时,为了使p 保持设置,您可能还需要将p 设为全局。
        • 我尝试将其发布为 cmets,但 cmets 有字符数限制。对此感到抱歉。
        • > 如果程序在到达 free 之前退出(或者根本没有释放),并且 p 保持设置,那么 valgrind 将认为分配的内存可能丢失。哦,我明白了
        猜你喜欢
        • 2011-04-05
        • 2011-07-26
        • 1970-01-01
        • 2016-06-30
        • 2013-07-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-06-23
        相关资源
        最近更新 更多