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

时间:2016-02-02 03:29:48

标签: c arrays string valgrind

我正在尝试使用fscanf从C中的文本文件中读取单词并将它们放入动态分配的数组中。但是,我一直在Valgrind中遇到错误,并且(null)字符似乎在我的输出中弹出。我创建了一个双指针** str_array来保存每个字符数组,并最初为4个字符数组分配足够的空间。 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)

1 个答案:

答案 0 :(得分:2)

free循环中有错误:

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

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