Why should I use my own buffer for getline or similar functions?

I was writing a program the other day when I was using a function getline()

and I realized something that I never thought of and could not find anything about it on the internet.

As described getline

on the man page:

DESCRIPTION

The function getdelim()

reads a string from the stream, delimited by a character separator. The function is getline()

equivalent to getdelim()

the newline character as a separator. The delimiter character is included as part of the line if the end of the file is not reached.

The caller can supply a pointer to the malloced buffer for line at *linep

and the capacity of that buffer at *linecapp

. These functions expand the buffer as needed, as if through realloc()

. If linep

points to a pointer NULL

, a new buffer will be allocated. In any case, *linep

and *linecapp

will be updated accordingly.

Usually when I use this function, I always malloc my own buffer and pass it to the getline funline pipe, but after reading this I realized that this is not necessary since it will only be created.

My question is, is there a reason why I should create my own buffer and then pass it to getline and not just pass NULL

and let getline process the buffer?

The only reason I could think of is if you want to control the size of the buffer, but that doesn't seem right because it says it will resize the buffer as needed.

When should I use my own buffer, and when should I let getline handle the creation of the buffer?

+3


source to share


2 answers


Q: Is there a reason why I should create my own buffer and then pass it to getline and not just pass NULL and let getline handle the buffer?
A: Generally not. In some situations, it makes sense to highlight the selection before calling getline()

.

1) Many redistribution schemes getline()

are liner. That is, it will allocate a buffer of N bytes (e.g. 256, 1k, 4k). Then if that isn't enough, try 2 * N, 3 * N, 4 * N, 5 * N, etc. If for some reason the code expects regular large buffer needs, allocating one large buffer before calling will getline()

prevent the getline()

small buffers from being moved again. Potential, if questionable, efficiency gains.

  size_t size = 10000;
  char *buf = mallc(size);
  ssize_t numchar = getline(&buf, &size, ...);

      

2) If the code is needed or has a working buffer available before the call getline()

, it's ok to use.



  size_t size = 100;
  char *buf = mallc(size);
  ...
  foo(buf, size);
  ...
  // No need for these steps
  // free(buf);
  // size = 0;
  // buf = NULL;
  ...
  ssize_t numchar = getline(&buf, &size, ...);
  ...
  free(buf);

      

3) Repeated calls. This includes a loop in which calls are repeated getline()

. No need to free in the loop, wait for the loop to complete. @Alan Stokes

  // do not use this
  while (some_condition) {
    size_t size = 0;
    char *buf = NULL;
    ssize_t numchar = getline(&buf, &size, ...);
    foo(numchar, buf,size);
    free(buf);
  }  

  // instead, use this model
  size_t size = 0;
  char *buf = NULL;
  while (some_condition) {
    ssize_t numchar = getline(&buf, &size, ...);
    foo(numchar, buf,size);
  }  
  free(buf);

      

Q2: When should I use my own buffer, and when should I let getline handle creating the buffer?
A2: Allocate your own buffer when the code certainly needs or benefits from it. Else let getline()

do it.

+3


source


  • No reason, the buffer is needed realloc

    d as needed and you need free

    it yourself. So you can just pass NULL

    to make sure it gets through length == 0

    .

  • I don't see a situation where it would be good to use your own dedicated buffer, you would still use malloc

    and what to use getline

    getdelim

    .



Of course, if you pass a large enough buffer, you would disallow calling realloc

on each getline

, but you can test with valgrind

, and for most common cases there will be as few calls as possible realloc

.

0


source







All Articles