c - 即使在使用 free() 之后,Valgrind 也会报告丢失的字节

标签 c valgrind dynamic-memory-allocation

在阅读有关内存分配的内容后,我一直在尝试用 C 语言进行一些操作。一切似乎都相当柔和和引人注目,直到我陷入了这个程序。它按预期工作,但 valgrind 清楚地说明了一个完全不同的故事。这是我的程序:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define NSTRINGS 3

int main()
{
    char **v = NULL;
    int sum = 0;
    char str[80]={'\0'};
    int i = 0, pos = 0;
    v = (char**) calloc((NSTRINGS * sizeof(char*)),1);

    while(1)
    {
        for(i = 0; i < NSTRINGS; i++)
        {
            printf("[%d] ", i+1);
            if(v[i] == NULL)
                printf("(Empty)\n");
            else
                printf("%s\n", v[i]);
        }

        do        
        {
            printf("New string's position (1 to %d): ", NSTRINGS);
            scanf("%d", &pos);
            getchar(); /* discards '\n' */
        }
        while(pos < 0 || pos > NSTRINGS);

        if (pos == 0){
            i = 0;
            break;
        }
        else{
            printf("New string: ");
            fgets(str, 80, stdin);
            str[strlen(str) - 1] = '\0';
            v[pos - 1] = realloc(v[pos - 1], strlen(str)+1);
            strcpy(v[pos - 1], str);
        }
    }
    free(v);
    v = NULL;
    return 0;
}

唯一的目标是根据所需的空间分配 3 个字符串(以保留未使用的字符串)。但是,即使在使用 free(v) 之后,这就是 valgrind 返回给我的内容(按 1 2 3 然后 0 的顺序填充它们):

[...]
==6760== 
==6760== HEAP SUMMARY:
==6760==     in use at exit: 20 bytes in 3 blocks
==6760==   total heap usage: 6 allocs, 3 frees, 2,092 bytes allocated
==6760== 
==6760== 20 bytes in 3 blocks are definitely lost in loss record 1 of 1
==6760==    at 0x4C2FA3F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6760==    by 0x4C31D84: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6760==    by 0x4009EB: main (in /home/esdeath/Prog/PL2/a.out)
==6760== 
==6760== LEAK SUMMARY:
==6760==    definitely lost: 20 bytes in 3 blocks
==6760==    indirectly lost: 0 bytes in 0 blocks
==6760==      possibly lost: 0 bytes in 0 blocks
==6760==    still reachable: 0 bytes in 0 blocks
==6760==         suppressed: 0 bytes in 0 blocks
==6760== 
==6760== For counts of detected and suppressed errors, rerun with: -v
==6760== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0

因此,我有两个问题一直想回答,但恐怕我的经验目前还不允许我回答:

  • 首先,它声明我有 3 个分配,即使我从未使用/达到 realloc 函数。这是否意味着 calloc 函数单独使用了 3 个分配?如果是这样,为什么?

  • 其次,我怎样才能准确释放这 20 个字节(在这种情况下)?我真的很困惑...

提前致谢。

<小时/>

旁注:我认识到“realloc”可能返回 NULL(如果失败),我将其添加到程序中。除非放置错误,否则 Valgrind 会继续报告相同的问题,所以我最终将其删除(在撤消过程中)...

最佳答案

您没有释放realloc分配的内存。添加

for (int i = 0; i < NSTRINGS; ++i)
    free(v[i]);

之前

free(v);

关于c - 即使在使用 free() 之后,Valgrind 也会报告丢失的字节,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54851740/

相关文章:

c - 为什么这些可以声明为整数?

通过 M<N 的 GSL 计算矩阵的零空间会产生错误

c - 我该如何处理垃圾?

c++ - 使用大小为 8 的未初始化值。C++

c++ - 大小为 1 的无效写入,地址 0x... 未堆栈、malloc 或(最近)释放 (Valgrind)

c - 为什么 valgrind 报告 glibc tsearch() 随机泄漏内存?

c++ - Linux C++ 中的页面对齐内存分配

c - 为什么 C 管理堆,而不是操作系统?

c - 我做错了什么 - C 指针

C 代码指针谜题