0

I'm trying to get unlimited input from user, using realloc. this is what i've done so far:

int getCharactersFromUser(char* arr,char terminator)
{
char c = getch();
int length =0;
while(c!=terminator)
    {
    arr = realloc(arr, sizeof (arr)*(++length));
    arr[length-1]=c;
    c = getch();
    }
return length;
}

i call this method with an arr like this: char *unknownArr = calloc(0,sizeof *unknownArr); int length = getCharactersFromUser(&unknownArr,TEMINATOR_FOR_LIST); here TEMINATOR_FOR_LIST is eof

limido
  • 327
  • 2
  • 14

1 Answers1

7

If you want to change the caller's copy of arr, you need to pass a pointer to a pointer.

Also, sizeof (arr) gives you the size of char*; your code appears to be assuming sizeof(char). This is guaranteed to be 1, allowing your memory size calculation to be simplified.

int getCharactersFromUser(char** arr,char terminator)
{
    *arr = NULL; // first call to realloc will crash if `*arr` is uninitialised in caller
    char c = getch();
    int length =0;
    while(c!=terminator)
    {
        *arr = realloc(*arr, ++length);
        (*arr)[length-1]=c;
        c = getch();
    }
    return length;
}
simonc
  • 41,632
  • 12
  • 85
  • 103
  • 2
    This also seems like the kind of situation where it'd be better to realloc in powers of two, doubling each time. (Of course, that means that more than one character can be read between reallocations.) – Joshua Taylor Dec 02 '13 at 20:56
  • Instead of *arr = NULL, which has the potential for leaking, I would use if(!*arr) *arr = malloc(1); Also, what @JoshuaTaylor said. if(maxlen == curlen) *arr = realloc(*arr, (maxlen *= 2)); – ciphermagi Dec 02 '13 at 21:03
  • 1
    @JonahNelson Your version will crash if an uninitialised pointer is passed in. The OP will have to choose which one form of misuse to guard against and document his/her function appropriately. – simonc Dec 02 '13 at 21:04
  • can u explain why do i need a pointer to a pointer? isn't a pointer to a start of address enough? – limido Dec 02 '13 at 21:27
  • If you want the caller to be able to access `str`, you have to pass the address of their variable into `getCharactersFromUser`. Their variable is a `char*` so the address of this is a `char**`. – simonc Dec 02 '13 at 21:30
  • now i'm calling it like this: `&unknownArr` and i get a warning "assigment makes pointer from integer without a case". – limido Dec 02 '13 at 21:36
  • Are you talking about the code at the bottom of your question? I'm afraid I don't understand it. It doesn't call `getCharactersFromUser` or match its signature. Is it related to `getCharactersFromUser` or could it be separated into a different question? – simonc Dec 02 '13 at 21:41
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/42366/discussion-between-user2719361-and-simonc) – limido Dec 02 '13 at 21:58
  • Hmm...at a guess, have you forgotten to `#include ` for a definition of `calloc`? (ansii C will assume that a function with no definition returns `int`) – simonc Dec 02 '13 at 22:00