-2

I'm trying to take an unknown amount of lines of console input, convert each line to a String using malloc, and then add each string to an array of strings by dynamically reallocating memory each time. My goal is to have an array where each element is a different line entered by the console (the while loop should end with EOF).

My code is below.

char * inputString = (char *)malloc(100);
char * aWord = (char *)malloc(1);
char ** listWords = (char **)malloc(1);
int wordCount = 0;

while (fgets(inputString, 100, stdin) != NULL)
{       
    wordCount++;
    *(inputString + (strlen(inputString) - 1)) = '\0';
    aWord = (char *)realloc(aWord, strlen(inputString) + 1);
    aWord = inputString;

    listWords = realloc(listWords, sizeof(char) * wordCount);
    *(listWords + (wordCount - 1)) = aWord;
}

for (int i = 0; i < wordCount; i++)
    printf("%s\n", listWords[i]);

If I were to input in console

abc\n
b\n
cad\n
^Z\n

In theory, I would like my code to print out

abc\n
b\n
cad\n

Each line of console input. Instead it prints

cad\n
cad\n
cad\n

The last line entered. Help much appreciated

Weather Vane
  • 33,872
  • 7
  • 36
  • 56

3 Answers3

1

You can't copy a string using an assignment, you have to use strcpy():

strcpy(aWord, inputString);

Also,

*(listWords + (wordCount - 1)) = aWord;

can be simplified to:

listWords[wordCount-1] = aWord;
Barmar
  • 741,623
  • 53
  • 500
  • 612
1

First is this:

aWord = (char *)realloc(aWord, strlen(inputString) + 1);
aWord = inputString;

Here you allocate space for aWord, but then overwrite the returned address with the address contained in inputString. So each string you read in ends up overwriting the previous string. You also should be using malloc instead of realloc because you want to get a new buffer instead of resusing an existing one.

Change the realloc call to malloc and instead of assigning one pointer to the other, usestrcpy` to copy it.

aWord = malloc(strlen(inputString) + 1);
strcpy(aWord, inputString);

Then on this line:

listWords = realloc(listWords, sizeof(char) * wordCount);

You only allocate enough memory for an array of characters instead of an array of pointers to characters. This results in writing past the end of allocated memory, invoking undefined beahvior.

The proper allocation is:

listWords = realloc(listWords, sizeof(char *) * wordCount);
dbush
  • 205,898
  • 23
  • 218
  • 273
1

There are three issues.

First, realloc does not allocate an additional aWord but increases/decreases the buffer of the current aWord, thereby probably giving back a new address while releasing the old one. So aWord = (char *)realloc(aWord, strlen(inputString) + 1) will adapt the memory to a new size, but you will loose the content written to aWord previously. Note that *(listWords + (wordCount - 1)) = aWord will let your final list point to aWord. Use malloc instead of realloc.

Second, with aWord = inputString;, you let aWord point to inputString instead of copying its contents. Use strcpy instead:

char *aWord = malloc(aWord, strlen(inputString) + 1);
strcpy (aWord,inputString);

Third, you need to reserve space for character pointers, not just characters.

listWords = realloc(listWords, sizeof(char*) * wordCount);
Stephan Lechner
  • 34,891
  • 4
  • 35
  • 58