【问题标题】:Memory leak with function getline. (Still reachable)函数 getline 的内存泄漏。 (仍然可以到达)
【发布时间】:2021-08-06 17:32:38
【问题描述】:

这是我的一段代码(目的是读取行并从中构建结构):

typedef struct{
   size_t length;
   char *letters;
}line;
static line ReadLine(){
    char *buffor = NULL;
    size_t length = 0;
    int nRead = 0;
    nRead = getline(&buffor, &length, stdin);
    return nRead == -1 ? (line) {.length = 0, .letters = NULL} : (line) {.length = nRead, .letters = buffor};
}

稍后在我的 main 函数中,我释放了由 getline 函数分配的缓冲区:

void ReadFile(){
line l = ReadLine();
printLine(l);
free(l.letters);
}

但我知道有一些内存(使用 valgrind):Leak_StillReachable by malloc,其中函数 getline 是。

【问题讨论】:

  • 你如何“得到”有一些内存没有被释放?有什么工具能告诉你吗?它说什么?显示该工具的确切输出。或者你是从你的程序的行为中推断出来的。什么行为?编辑问题以提供minimal reproducible example
  • 我使用了 valgrind(edited initial post),并且在函数 getline() 所在的同一行中得到了 Leak_StillReachable。
  • 我已经用 valgrind 测试了你的代码:“所有堆块都被释放了——不可能有泄漏”。如果出现这种情况,您能否提供printLine 函数?
  • 它不会以任何方式修改缓冲区,只是使用 printf 函数打印它。虽然我使用的是 Clion valgring,但这可能是个问题?
  • 那我猜是你本地的 libc getline 实现有问题(见this question as example

标签: c memory memory-management memory-leaks valgrind


【解决方案1】:

好的,所以过了一段时间我发现如果 getline() 分配内存失败,它仍然会分配缓冲区,所以如果 nRead == -1(表示 getline 中的错误)我们必须释放缓冲区。否则我返回

(line) {.length = 0, .letters = NULL}

我丢失了一个指向缓冲区的指针,尽管分配了错误。

【讨论】:

    【解决方案2】:

    getline() 的内存应该使用 malloc() 分配,尝试将 line (char* buffor = NULL) 更改为 line (char* buffor = (char*)malloc(count * sizeof(char)); ) 其中 count 是输入字符串的最大长度。

    【讨论】:

    • getline() 调用 realloc 如果没有足够的空间分配,这可能会导致你提到的问题。
    • "如果 *lineptr 为 NULL,则 getline() 将分配一个缓冲区用于存储该行,该缓冲区应由用户程序释放。(在这种情况下,*n 中的值被忽略。)" (man getline)
    • realloc的情况下,前面分配的空间被realloc释放:"如果内存对象的新大小需要移动对象,前一个空间对象的实例化被释放”
    • 没有指定最大输入长度。
    猜你喜欢
    • 1970-01-01
    • 2011-04-19
    • 2022-01-05
    • 2014-04-09
    • 1970-01-01
    • 1970-01-01
    • 2013-07-13
    相关资源
    最近更新 更多