This looks very odd. You realloc once when idx == WORD_SIZE but if
2 * WORD_SIZE is not enough, then what?
How about adding idx = 0; after new_mem line ?
You have both a memory leak and logic error here. As I pointed out
before, when you allocate new memory you must make pw_begin point to
the right place. You've change the code, but not made it correct
yet. If the realloc is OK, you need pw_begin to point (about) idx
places into new_mem.
you pointed it out in get_words code but this function you quoted is
get_single_word. ppc is the pointer to pointer to char that you get from
function argument, which will be passed to free() in main(). pw_begin is
used to put input characters into the array. so both ppc and pw_begin need
to point to new_mem. right ?
The leak is caused only when realloc fails. You set *ppc to NULL (the
return from realloc) but that loses the pointer to the word so it can
now ever be freed.
okay, I have added an else statement aligning with if clause.
You need also to check all your index counts. This will write the at
index 3 into a string of length 3 (i.e. out of bounds) and the text for
reallocation is wrong as well. You need to realloc space when idx ==
WORD_SIZE - 2 (I think) since idx in incremented late and you must have
space for the null. Anyway, check them (and use valgrind).
I really did not understand what you mean. I mean, i am unable to
comprehend what you said. This is my new code with buggy output:
/* A program that takes a single word from input
* it uses a while loop and dynamic memory allocation to take
* continuous input form user
*
* VERSION: 1.1
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
enum { WORD_SIZE = 3 };
enum { GSW_OK, GSW_ENOMEM, GSW_ENORESIZE } ;
int get_single_word( char** );
int main( void )
{
char* pword;
while( (GSW_OK == get_single_word(&pword)) && ( *pword != 0) )
{
printf("You entered: [%s]\n", pword);
}
return 0;
}
int get_single_word( char** ppc )
{
unsigned idx;
int ch;
size_t arr_size;
char* pw_begin;
char* new_mem;
arr_size = WORD_SIZE;
*ppc = malloc(arr_size * sizeof(**ppc));
pw_begin = *ppc;
if( NULL == ppc )
{
return GSW_ENOMEM;
}
while( (EOF != (ch = getchar())) && isspace(ch) )
{
continue; /* trailing whitespace */
}
if( EOF != ch )
{
*pw_begin++ = ch;
}
for( idx = 0; (EOF != (ch = getchar())) && (! isspace(ch)); ++idx )
{
if( (WORD_SIZE - 1) == idx ) /* -1 for '\0' character*/
{
new_mem = realloc( *ppc, (2 * WORD_SIZE * sizeof **ppc) );
if( NULL == new_mem )
{
*pw_begin = '\0';
return GSW_ENORESIZE;
}
else
{
pw_begin = *ppc = new_mem;
idx = 0;
}
}
*pw_begin++ = ch;
}
*pw_begin = '\0';
return GSW_OK;
}
========================= OUTPUT =======================================
[arnuld@dune ztest]$ gcc -ansi -pedantic -Wall -Wextra get-single-word.c
[arnuld@dune ztest]$ ./a.out
Richard Heathfield
You entered: [rd]
You entered: [d]
Party
You entered: [ty]
[arnuld@dune ztest]$