DeadCake
DeadCake

Reputation: 467

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

I'm trying to read in words from a text file in C using fscanf and putthem into a dynamically allocated array. However, I keep getting errors in Valgrind and (null) characters seem to be popping up in my output. I create a double pointer **str_array to hold each character array and initially allocate enough space for 4 character arrays. fscanf runs and stores the read in string into str[] and I use strcpy to copy str[]'s string into str_array. I realloc memory if str_array needs to hold more strings.

#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;
}

Here's the Valgrind error code.

==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)

Upvotes: 0

Views: 2656

Answers (1)

paddy
paddy

Reputation: 63471

You have an error in the free loop:

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

The array index should be i, not word_count.

Upvotes: 2

Related Questions