The getline() Function – Update

Back in early 2015, I wrote about the getline() function, which is a handy way to read a string. I’ve been informed that my post is the top result for a Google search on getline() — and I have an update!

In my post, I showed how to create storage for the getline() function’s first argument, the address of a pointer — the buffer to hold input. This step is unnecessary as the getline() function automatically allocates storage for the input string, but only providing that you first initialize the buffer’s address to NULL.

Here is an update to my getline() sample code from back in 2015:

2022_07_09-Lesson-a.c

#include <stdio.h>

int main()
{
    char *buffer = NULL;
    size_t bufsize = 32;
    size_t characters;

    printf("Type something: ");
    characters = getline(&buffer,&bufsize,stdin);
    printf("%zu characters were read.\n",characters);
    printf("You typed: '%s'\n",buffer);

    return(0);
}

The char pointer buffer is declared and initialized at Line 5. This step is important! You must set the location to NULL or the program crashes. (I suppose that getline() tests for NULL to determine whether to allocate storage.) The program runs if you choose to instead allocate the buffer, as I did in the original post, but why bother if the function allocates (and reallocates) storage anyway?

Aside from initializing buffer, the remainder of the code (above) is the same as the original. Here’s sample output:

Type something: Today is July 9, 2022
22 characters were read.
You typed: 'Today is July 9, 2022
'

In my original post, I next went on to describe how to use getline() with an array. So instead of:

char *buffer = NULL;

I specified this ugly monster:

char buffer[32];
char *b = buffer;

This technique is classified as unpredictable. The reason that disaster looms is when the getline() function reallocates storage, which it can do when input exceeds the value set in the second argument. (An amazing trick!) Here is the sample code for reference:

2022_07_09-Lesson-b.c

#include <stdio.h>

int main()
{
    char buffer[32];
    char *b = buffer;
    size_t bufsize = 32;
    size_t characters;

    printf("Type something: ");
    characters = getline(&b,&bufsize,stdin);
    printf("%zu characters were read.\n",characters);
    printf("You typed: '%s'\n",buffer);

    return(0);
}

Here is the output (macOS) when I overflow the buffer:

Type something: This is a very long string that overflows the buffer
a.out(48229,0x111d55600) malloc: *** error for object 0x7ff7bdcf78b0: pointer being realloc'd was not allocated
a.out(48229,0x111d55600) malloc: *** set a breakpoint in malloc_error_break to debug
Abort trap: 6

If I try to overflow the buffer with the pointer example, I see this output:

Type something: This is a very long string that overflows the buffer
53 characters were read.
You typed: 'This is a very long string that overflows the buffer
'

Obviously, the first method works and the second does not. Please avoid using an array with the getline() function!

In next week’s Lesson, I play around with getline() to further test its guts.

2 thoughts on “The getline() Function – Update

  1. “the getline() function reallocates storage, which it can do when input exceeds the value set in the second argument”

    I might have misunderstood but that seems to mean getline just reallocs as much memory as it needs for the user’s input irrespective of the second argument. If so you could remove the bufsize variable and just pass 0 instead.

  2. You must still pass a pointer, so you can pass a pointer to zero. I was nervous to try it, but it works!

Leave a Reply