I have trouble with storing strings in an array from input. I want to store it from input ending with EOF and be able to store any amount of strings of any length. Here is my code:
char **list = (char**)malloc(sizeof(char*));
char c = getchar();
int i, j, count = 0;
int size = 0;
char * string = NULL
while (c != EOF)
{
size = 0;
while (c != EOF && c != '\n')
{
string = (char*)realloc(string,size+1); //line 210
string[size] = c;
size++;
c = getchar();
}
list = (char**)realloc(list, (count+1)*sizeof(char*));
list[count] = string;
++count;
string = NULL;
c = getchar();
}
for (j = 0; j < count; ++j) //trying to print out all the strings
{
printf("%s\n", list[j]); //line 237
}
free(string);
free(list);
return (EXIT_SUCCESS);
I know I should also be testing whether all the allocs where successful, but that is not my issue right now. The program works properly when compiled with gcc -Wall -pedantic, but valgrind gives the following errors:
==2601== Memcheck, a memory error detector
==2601== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==2601== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==2601== Command: ./a.out -g
==2601==
asd
dsa
==2601== Invalid read of size 1
==2601== at 0x4C30F74: strlen (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2601== by 0x4EA95DB: puts (ioputs.c:35)
==2601== by 0x4008E8: main (testing.c:237)
==2601== Address 0x52035c3 is 0 bytes after a block of size 3 alloc'd
==2601== at 0x4C2FD5F: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2601== by 0x40080D: main (testing.c:210)
==2601==
asd
dsa
==2601==
==2601== HEAP SUMMARY:
==2601== in use at exit: 12 bytes in 4 blocks
==2601== total heap usage: 14 allocs, 10 frees, 2,101 bytes allocated
==2601==
==2601== LEAK SUMMARY:
==2601== definitely lost: 12 bytes in 4 blocks
==2601== indirectly lost: 0 bytes in 0 blocks
==2601== possibly lost: 0 bytes in 0 blocks
==2601== still reachable: 0 bytes in 0 blocks
==2601== suppressed: 0 bytes in 0 blocks
==2601== Rerun with --leak-check=full to see details of leaked memory
==2601==
==2601== For counts of detected and suppressed errors, rerun with: -v
==2601== ERROR SUMMARY: 2 errors from 1 contexts (suppressed: 0 from 0)
Instead of
freeingstringat the end of the program, you need to free the memory allocated for each of the strings that you read:To fix the
"Invalid read of size 1"error, you need to change:You are using
sizeas the index forstring, so you need to increment this value before adding a space for the '\0' in the allocation. Better variable names would have helped avoid this issue. Consider changingsizetoindex.Note also that you need
cto be anintin order to store theEOFcharacter, so change:Also, this code is failing to terminate the strings with a
NUL. You need to add:When you initialize
listat the beginning of the program, there is no need to allocate space yet, and you just end upreallocing it anyway, so:And notice that I removed the casts from the calls to
malloc()andrealloc(). These are not needed in C, and mostly serve to clutter the code. Similarly, instead of usingsizeof(char*)here, I usedsizeof(*list), which is less error-prone and much more clear.