Warm tip: This article is reproduced from serverfault.com, please click

c-Valgrind跳转或移动取决于使用getline和一个char的未初始化值*

(c - Valgrind jump or move depends on uninitialised value(s) using getline and one char *)

发布于 2020-11-29 22:01:28

我正在尝试使用getline和一个char指针来存储getline该指针的所有结果


    char *final = NULL;
    char *line = NULL;
    size_t n = 0;
    ssize_t result;
    int current_size = 0;
    while ((result = getline(&line, &n, in)) != -1){
        current_size += result;
        final = realloc(final, current_size ); //valgrind error
        if (final== NULL)
            return NULL;
        strcat(final,line);
    }


但是我总是得到错误:

==695== Conditional jump or move depends on uninitialised value(s)
==695==    at 0x483B6D0: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==695==    by 0x483E017: realloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
... method trace

我知道,重新分配只是分配而不是初始化值,但是如果我尝试在下一行进行内存设置,则valgrind会告诉我:

==695== Conditional jump or move depends on uninitialised value(s)
==695==    at 0x48428EC: memset (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
... method trace

我阅读了很多SO文章,但是无法通过其中显示的解决方案解决该问题。我敢肯定这不是最严重的内存泄漏,但这仍然是最严重的泄漏,因此我正在尝试解决此问题。有谁知道如何解决这个问题?

Questioner
luFlo
Viewed
12
David C. Rankin 2020-11-30 06:38:40

你已经很接近了,但是你current_size += result;在调用之前使用realloc()阻止进行简单检查,current_size == 0以检查你希望将其初始化final空字符串的第一次迭代

你可以执行以下操作:

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

int main (void) {

    char *final = NULL, *line = NULL;
    size_t n = 0, current_size = 0;
    ssize_t result;
    
    while ((result = getline(&line, &n, stdin)) != -1) {
        if (result > 0)
            line[--result] = 0;                                 /* trim \n */
        
        final = realloc (final, current_size + result + 1);     /* add room for \0 */
        if (final== NULL)                                       /* validate allocation */
            return 1;
        
        if (!current_size)                                      /* if 1st word */
            *final = 0;                                         /* make final empty-str */
        
        current_size += result;                                 /* now update value */
        strcat (final, line);                                   /* concatenate */
    }
    
    printf ("%zu - %s\n", current_size, final);
    
    free (final);
    free (line);
}

使用/输出示例

$ ./bin/getlineplusone << 'eof'
1234
56
789
eof
9 - 123456789

内存使用/错误检查

$ valgrind ./bin/getlineplusone << 'eof'
1234
56
789
eof
==8438== Memcheck, a memory error detector
==8438== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==8438== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==8438== Command: ./bin/getlineplusone
==8438==
9 - 123456789
==8438==
==8438== HEAP SUMMARY:
==8438==     in use at exit: 0 bytes in 0 blocks
==8438==   total heap usage: 6 allocs, 6 frees, 5,262 bytes allocated
==8438==
==8438== All heap blocks were freed -- no leaks are possible
==8438==
==8438== For counts of detected and suppressed errors, rerun with: -v
==8438== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)