get a line from file pointer & pointer doesn't seem to free correctly

Discussion in 'C Programming' started by Jeff Rodriguez, Nov 15, 2003.

  1. There has GOT to be a standard way to this. I'm sure I'm not the only
    person who would want to have a function that gets one line from a file
    pointer with a dynamic length. Here's what I have right now:

    ( also at http://gurugeek.com/jeff/programming/wordjumble/wordjumble.c )

    void get_line( FILE *fp, char **line )
    {
    int ch;
    int iteration = 0;
    char *tmp = NULL;

    /* {{{ Code Fold: Loop until we reach EOF or a newline */
    while ( (ch = fgetc(fp)) != '\n' && !feof(fp))
    {
    /* {{{ Code Fold: (Re)allocate Memory */
    if ((tmp = realloc((*line), (iteration + 2) * sizeof(char))) ==
    NULL )
    {
    puts("Memory reallocation failed\n");
    exit(EXIT_FAILURE);
    }
    else
    {
    *line = tmp;
    }
    /* }}} Code Fold: (Re)allocate Memory */

    (*line)[ iteration ] = (char)ch;
    iteration++;
    }
    /* }}} Code Fold: Loop until we reach EOF or a newline */

    }


    Also, my main function:

    int main( int argc, char *argv[] )
    {
    unsigned int count = 0;

    while ( !feof(stdin) )
    {
    char *line = NULL;

    count++;
    printf("> ");
    get_line(stdin, &line);
    printf("%s\n", line);
    // Don't forget to
    free(line);
    }
    printf("\nTotal lines: %u\n", count);
    return EXIT_SUCCESS;
    }

    Together they seem to give some unexpected output:

    jeff@andromeda% gcc wordjumble.c
    jeff@andromeda% ./a.out
    > long string

    long string
    > short

    shortstring
    >



    I'm freeing 'line' so that's the problem?
    Jeff Rodriguez, Nov 15, 2003
    #1
    1. Advertising

  2. Jeff Rodriguez

    Morris Dovey Guest

    Jeff Rodriguez wrote:

    > There has GOT to be a standard way to this. I'm sure I'm not the only
    > person who would want to have a function that gets one line from a file
    > pointer with a dynamic length. Here's what I have right now:


    <code snipped>

    > Together they seem to give some unexpected output:
    >
    > jeff@andromeda% gcc wordjumble.c
    > jeff@andromeda% ./a.out
    >
    >> long string

    >
    > long string
    >
    >> short

    >
    > shortstring
    >
    > I'm freeing 'line' so that's the problem?


    Jeff...

    You're forgetting to terminate the input string with '\0'.

    --
    Morris Dovey
    West Des Moines, Iowa USA
    C links at http://www.iedu.com/c
    Read my lips: The apple doesn't fall far from the tree.
    Morris Dovey, Nov 15, 2003
    #2
    1. Advertising

  3. Jeff Rodriguez wrote:

    > There has GOT to be a standard way to this.


    No. There are lots of ways to do this, and none of them is standard (perhaps
    because nobody could decide which was the best way?).

    > I'm sure I'm not the only
    > person who would want to have a function that gets one line from a file
    > pointer with a dynamic length.


    You're right. You're not. I now have several ways to do this, and I'm not
    the only one either. See http://users.powernet.co.uk/eton/c/fgetdata.html
    for a discussion of this problem (you will also find links to my own
    fgetline() and fgetword() functions), or grep Google Groups for Chuck
    Falconer's ggets function, which takes yet another approach to the problem.

    > Here's what I have right now:
    >
    > ( also at http://gurugeek.com/jeff/programming/wordjumble/wordjumble.c )
    >
    > void get_line( FILE *fp, char **line )
    > {
    > int ch;
    > int iteration = 0;
    > char *tmp = NULL;
    >
    > /* {{{ Code Fold: Loop until we reach EOF or a newline */
    > while ( (ch = fgetc(fp)) != '\n' && !feof(fp))
    > {
    > /* {{{ Code Fold: (Re)allocate Memory */
    > if ((tmp = realloc((*line), (iteration + 2) * sizeof(char))) ==
    > NULL )


    This is going to be slow. Very slow. You realloc /every/ time you retrieve a
    character.

    > {
    > puts("Memory reallocation failed\n");
    > exit(EXIT_FAILURE);
    > }
    > else
    > {
    > *line = tmp;
    > }
    > /* }}} Code Fold: (Re)allocate Memory */
    >
    > (*line)[ iteration ] = (char)ch;
    > iteration++;
    > }
    > /* }}} Code Fold: Loop until we reach EOF or a newline */


    Don't you think it would be a cool idea to null-terminate this "string" at
    some point? :)

    --
    Richard Heathfield :
    "Usenet is a strange place." - Dennis M Ritchie, 29 July 1999.
    C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
    K&R answers, C books, etc: http://users.powernet.co.uk/eton
    Richard Heathfield, Nov 15, 2003
    #3
  4. Jeff Rodriguez

    Morris Dovey Guest

    Jeff Rodriguez wrote:

    > I'm sure I'm not the only person who would want to have a
    > function that gets one line from a file pointer with a dynamic
    > length.


    You're not. Nearly everyone writes at least one function to do
    that job. If you're interested in recursion, you're invited to
    look at a function I wrote that waits until the line is complete
    before allocating an (exact sized) buffer:

    http://www.iedu.com/mrd/c/getsm.c

    --
    Morris Dovey
    West Des Moines, Iowa USA
    C links at http://www.iedu.com/c
    Read my lips: The apple doesn't fall far from the tree.
    Morris Dovey, Nov 15, 2003
    #4
  5. Morris Dovey wrote:

    > Jeff Rodriguez wrote:
    >
    >> There has GOT to be a standard way to this. I'm sure I'm not the only
    >> person who would want to have a function that gets one line from a
    >> file pointer with a dynamic length. Here's what I have right now:

    >
    >
    > <code snipped>
    >
    >> Together they seem to give some unexpected output:
    >>
    >> jeff@andromeda% gcc wordjumble.c
    >> jeff@andromeda% ./a.out
    >>
    >>> long string

    >>
    >>
    >> long string
    >>
    >>> short

    >>
    >>
    >> shortstring
    >>
    >> I'm freeing 'line' so that's the problem?

    >
    >
    > Jeff...
    >
    > You're forgetting to terminate the input string with '\0'.
    >

    Ahh, my origional code had that in there, then I posted another question
    on here and someone removed that piece of my code. I assumed that malloc
    / realloc would \0 it all out but I guess not.

    Thanks
    Jeff
    Jeff Rodriguez, Nov 15, 2003
    #5
  6. Jeff Rodriguez

    CBFalconer Guest

    Re: get a line from file pointer & pointer doesn't seem to freecorrectly

    Jeff Rodriguez wrote:
    >
    > There has GOT to be a standard way to this. I'm sure I'm not the
    > only person who would want to have a function that gets one line
    > from a file pointer with a dynamic length. ... snip ...


    There are several. Richard Heathfield has one, and so do I. Mine
    is designed for simplicity of use, and available at:

    <http://cbfalconer.home.att.net/download/ggets.zip>

    Get 'em, examine 'em, choose.

    --
    Chuck F () ()
    Available for consulting/temporary embedded and systems.
    <http://cbfalconer.home.att.net> USE worldnet address!
    CBFalconer, Nov 15, 2003
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Wiseguy
    Replies:
    2
    Views:
    327
    Jonathan Turkanis
    Jan 18, 2004
  2. scad
    Replies:
    23
    Views:
    1,155
    Alf P. Steinbach
    May 17, 2009
  3. mohammed_a_o
    Replies:
    0
    Views:
    269
    mohammed_a_o
    Nov 30, 2010
  4. Xeno Campanoli
    Replies:
    13
    Views:
    292
    Xeno Campanoli
    Jan 6, 2008
  5. Richard Schneeman
    Replies:
    16
    Views:
    477
    Daniel Bush
    Aug 27, 2008
Loading...

Share This Page