从文本文件中读取单词并存储到动态数组中 C 中的 Valgrind 错误

Read in Words from Text File and Store into Dynamic Array Valgrind Errors in C

我正在尝试使用 fscanf 从 C 语言的文本文件中读取单词,并将它们放入动态分配的数组中。但是,我在 Valgrind 中不断收到错误,并且(空)字符似乎在我的输出中弹出。我创建了一个双指针 **str_array 来保存每个字符数组,并最初为 4 个字符数组分配了足够的 space。 fscanf 运行并将读入的字符串存储到 str[] 中,我使用 strcpy 将 str[] 的字符串复制到 str_array 中。如果 str_array 需要容纳更多字符串,我会重新分配内存。

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

int main(int argc, char *argv[]) {
    char str[80];
    int word_alloc = 0;
    int word_count = 0;
    char **str_array;

    FILE *file;
    file = fopen(argv[1], "r");

    // Allocate memory to the array of strings (char arrays)
    word_alloc = 4;        
    str_array = (char **) malloc(sizeof(char*) * word_alloc);

    while (fscanf(file, "%s", str) != EOF) {
        // If there are more than 4 strings, double size
        if (word_count > word_alloc) {
            word_alloc *= 2;
            str_array = (char **) realloc(str_array, sizeof(char*) * word_alloc);
        }

        str_array[word_count] = (char *) malloc(sizeof(char) * (strlen(str) + 1));
        strcpy(str_array[word_count], str);
        ++word_count;
    }

    int i = 0;
    for (; i<word_count; i++) {
        printf("Word: %s\n", str_array[i]);
    }

    i = 0;
    for (; i<word_count; i++) {
        free(str_array[word_count]);
    }
    free(str_array);
    fclose(file);

    return 0;
}

这是 Valgrind 错误代码。

==6254== Memcheck, a memory error detector
==6254== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==6254== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==6254== Command: ./a.out readin-test.txt
==6254== 
==6254== Invalid write of size 8
==6254==    at 0x4008A6: main (readin-test.c:25)
==6254==  Address 0x51fc2e0 is 0 bytes after a block of size 32 alloc'd
==6254==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6254==    by 0x400835: main (readin-test.c:16)
==6254== 
==6254== Invalid read of size 8
==6254==    at 0x4008C0: main (readin-test.c:26)
==6254==  Address 0x51fc2e0 is 0 bytes after a block of size 32 alloc'd
==6254==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6254==    by 0x400835: main (readin-test.c:16)
==6254== 
==6254== Conditional jump or move depends on uninitialised value(s)
==6254==    at 0x4C2BDA2: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6254==    by 0x40094A: main (readin-test.c:37)
==6254==  Uninitialised value was created by a heap allocation
==6254==    at 0x4C2CE8E: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6254==    by 0x400871: main (readin-test.c:22)
==6254== 
==6254== 
==6254== HEAP SUMMARY:
==6254==     in use at exit: 999 bytes in 173 blocks
==6254==   total heap usage: 181 allocs, 8 frees, 5,631 bytes allocated
==6254== 
==6254== 999 bytes in 173 blocks are definitely lost in loss record 1 of 1
==6254==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6254==    by 0x4008A5: main (readin-test.c:25)
==6254== 
==6254== LEAK SUMMARY:
==6254==    definitely lost: 999 bytes in 173 blocks
==6254==    indirectly lost: 0 bytes in 0 blocks
==6254==      possibly lost: 0 bytes in 0 blocks
==6254==    still reachable: 0 bytes in 0 blocks
==6254==         suppressed: 0 bytes in 0 blocks
==6254== 
==6254== For counts of detected and suppressed errors, rerun with: -v
==6254== ERROR SUMMARY: 186 errors from 4 contexts (suppressed: 0 from 0)

您在 free 循环中出错:

i = 0;
for (; i<word_count; i++) {
    free(str_array[word_count]);
}

数组索引应该是i,而不是word_count