在我的代码中找不到“绝对丢失的内存”

时间:2019-07-08 16:12:11

标签: c heap valgrind

我正在尝试创建一些程序,以便为测试做好正确的准备,那将是很快的事情。 但是实际上,在对这些代码进行了几天的研究之后,我无法找到valgrind报告的内存泄漏实际上在哪里。

我尝试释放几乎所有内部​​和外部指针。我尝试释放一些不必要的指针,但没有任何结果。

这是结构:

typedef struct cop {
   int primo;
   int secondo;
   struct cop *next; 
 } coppia 

这些是功能:

coppia *crea_coppia(int x, int y)
{
    coppia *el=malloc(sizeof(coppia));
    el->primo=x;
    el->secondo=y;
    el->next=NULL;
    return el;
}

coppia *crea_coppia_bin(FILE *f)
{
    int buf[2];

    int e = fread(buf,sizeof(int),2,f);

    if(e!=2) return NULL;

    coppia *el = crea_coppia(buf[0],buf[1]);

    if(el==NULL) return NULL;

    return el;
}

coppia *crea_lista(char *nomefile)
{
    FILE *f = fopen(nomefile,"rb");
    coppia *lis=NULL;
    coppia *el=NULL;
    while(true)
    {
        el=crea_coppia_bin(f);
        if(el==NULL)
            break;
        lis=inserisci_coppia(lis,el);
    }
    fclose(f);
    return lis;
}

Valgrind输出:

==434== HEAP SUMMARY:
==434==     in use at exit: 16 bytes in 1 blocks
==434==   total heap usage: 9 allocs, 8 frees, 8,840 bytes allocated
==434==
==434== 16 bytes in 1 blocks are definitely lost in loss record 1 of 1
==434==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==434==    by 0x10896D: crea_coppia (provaesame.c:18)
==434==    by 0x1089D1: crea_coppia_bin (provaesame.c:53)
==434==    by 0x108A12: crea_lista (provaesame.c:77)
==434==    by 0x108B6D: main (provaesamemain.c:21)
==434==
==434== LEAK SUMMARY:
==434==    definitely lost: 16 bytes in 1 blocks
==434==    indirectly lost: 0 bytes in 0 blocks
==434==      possibly lost: 0 bytes in 0 blocks
==434==    still reachable: 0 bytes in 0 blocks
==434==         suppressed: 0 bytes in 0 blocks
==434==
==434== For counts of detected and suppressed errors, rerun with: -v
==434== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

这是将元素插入列表的函数:

coppia *inserisci_coppia(coppia *lis, coppia *el)
{
    if(lis==NULL)
    {
        lis=el;
        return lis;
    }
    else
    {
        el->next=lis;
        lis=el;
        return lis;
    }
}

这是释放功能:

void distruggi_lista_coppie(coppia *lis)
{
    while(lis!=NULL)
    {
        coppia *prossimo=lis->next;
        jr_free(lis);
        lis=prossimo;
    }
}

没关系,我找到了解决方案,这里有一个函数,我必须找到整个列表中的最大对,然后我必须单独打印出来。所以我将下一个元素的指针设置为NULL,这个最大元素是倒数第二个元素,所以最后一个元素丢失了。

2 个答案:

答案 0 :(得分:1)

绝对丢失的内存是尚未释放的内存,并且由于程序不再具有指向该内存的指针而无法释放。 (有关可能的内存泄漏类型的更完整列表,请参见Valgrind FAQ。)

如果不清楚,这是一个简单的示例:

char* buffer;
while (1) {
  buffer = malloc(BUF_LEN);
  if (fgets(buffer, BUF_LEN, stdin) == NULL) break;
  fprintf(stderr, "Read: %s", buffer);
  // process(buffer);
}

第二次通过循环,指向分配的内存的唯一指针丢失了,因为它没有被释放并且指向它的唯一指针被覆盖。由于程序不再具有指向第一个分配的buffer的指针,因此以后无法free()进行访问。

在实际的实现中,process可能会做一些保留指针的操作(例如,将其插入到链表中),或者甚至可能free()缓冲区,尽管有些人认为这样做很糟糕设计。如果它保存了指针,那么内存还没有确定的丢失,但是程序必须在某个时候运行存储的指针的存储库,并释放每个指针。

答案 1 :(得分:0)

我将添加自己的jr_mallocjr_free,然后看看正在调用什么。这些功能依次调用mallocfree

void *jr_malloc(size_t size)
{
    void *p = malloc(size);
    fprintf(stderr, "malloc: %d %p\n", size, p);
    return p;
}

void jr_free(void *p)
{
    fprintf(stderr, "free: %p\n", p);
    free(p);
}

您也许可以比较并查看哪些p没有被释放。