Valgrind合法的“可能丢失”字节的例子

时间:2012-07-31 11:19:34

标签: c++ c valgrind

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

  • 绝对丢失
  • 间接丢失
  • 可能丢失
  • 仍然可以访问
  • 抑制

我刚刚修复了一个漏洞,其中“可能丢失”是主要问题。

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

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

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

谢谢

3 个答案:

答案 0 :(得分:7)

文档是不同库的一些示例,这些库具有自己的分配器并且返回的内存不是直接由底层OS分配器(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)的原始返回指针并警告说。

答案 1 :(得分:5)

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);
}

答案 2 :(得分: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);
}

因为它看起来非常有趣,所以我确实运行了代码并对它进行了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)

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