Search code examples
cpointersdynamic-memory-allocationrealloc

Memory leak with malloc and fgetc


I'm having some trouble reading a like from user using malloc and getchar. I get the result, however, I get memory leaks using valgrind. I am pretty clueless in this and have asked my classmates and mentors, but none seem to find out why.

char *ReadLineFile(FILE *infile){
   int i=0;
   char c;
   char *newStringLine;
   newStringLine = (char *) malloc(sizeof(char));
   while( (c = fgetc(infile)) != '\n' ){
        newStringLine[i++] = c;
        realloc(newStringLine, (sizeof(char) * (i+1)));
   }
   newStringLine[i] = '\0';
   return newStringLine;
}

Valgrind gives me several errors, including Invalid write/read of 1, and invalid realloc.


Solution

  • Your usage of realloc() is erroneous.

    realloc(), if successful, frees the passed pointer and returns a new pointer with the allocated memory. You need to

    • catch the return value of realloc() in a temporary pointer,
    • check against NULL to ensure success and then

      • If returned pointer is not NULL, i.e., reallocation is successful, use the new pointer.
      • If the returned pointer is NULL, make some decisions and you can keep using the old pointer (passed as argument).

    Related, quoting C11, chapter §7.22.3.5

    The realloc function deallocates the old object pointed to by ptr and returns a pointer to a new object that has the size specified by size. [....]

    and,

    [...] If memory for the new object cannot be allocated, the old object is not deallocated and its value is unchanged.

    Otherwise, in case, realloc() is successful, you are (most probably) trying to use an already free-d memory, which , of course, causes undefined behavior.


    Uh-oh, and did I mention, please see this discussion on why not to cast the return value of malloc() and family in C?