-2

Im trying to implement a function with the following prototype.

int     get_next_line(const int fd, char **line) .   

The first parameter is the file descriptor that will be used to read.

The second parameter is the address of a pointer to a character that will be used to save the line read from the file descriptor.

The only thing i know about difference of passing reference and value is that referencing allows you modify the content value. But for the given prototype, we have the address of the first characters, so i don't fully understand the need for the double pointer.

[Edited] : We store one line of chars inside '**line'.

My question is:

Why use **line and not just *line , or why not ?

  • 5
    What kind of question is that? That's like what is the advantage of using `char` vs `float` in C? – melpomene Oct 15 '18 at 16:31
  • These are different types , one is a pointer to a string and the other is a string or array of chars. – newbie Oct 15 '18 at 16:32
  • Sorry i forgot to mention that we gonna store only one string inside the *line (array of chars). – Felix Riddick Oct 15 '18 at 16:36
  • In this context, it is kinda C's version of an OUT or INOUT parameter – Ctx Oct 15 '18 at 16:40
  • 5
    The more stars, the more luxurious the pointer is. – Petr Skocik Oct 15 '18 at 16:40
  • Does `get_next_line` allocate dynamic memory (with `malloc` or whatever) for the "next line"? If so, it needs to pass a pointer to the allocated memory back to the caller somehow. One way is to use a `char **line` parameter and set `*line` to point to the allocated memory. Another way is to change `get_next_line` to return a pointer to the allocated memory, changing its declaration to `char *get_next_line(int fd);`. (Note that there is no particular benefit in declaring the `fd` parameter as `const int fd`, but you can if you want to.) – Ian Abbott Oct 15 '18 at 16:41
  • Possible duplicate of [Why use double pointer? or Why use pointers to pointers?](https://stackoverflow.com/questions/5580761/why-use-double-pointer-or-why-use-pointers-to-pointers) – darnir Oct 15 '18 at 16:45
  • Perfectly valid question. The answer is simply if the *address of* `line` can change in `get_next_line` and you are NOT returning a pointer to the new address, then you **must** pass the address of the pointer. Otherwise your function receives a **copy** of the pointer (with its very own and very different address), and any changes made to its address (e.g. allocating and assigning storage, etc..) will not be available back in the calling function. Otherwise if `line` has adequate storage to begin with, you can simply pass it as a pointer (the copy contains the same address) – David C. Rankin Oct 15 '18 at 17:21

1 Answers1

2
int get_next_line(int fd, char **line);

This is a usable function. It presumably allocates a character array of tentatively sufficient size, reads a line into it, reallocates and reads the remainder if necessary, and then passes the allocated string back by assigning it to the dereferenced second argument (*line = allocated_string;).


int get_next_line(int fd, char *line);

This is patent nonsense. There is no way to write get_next_line that is remotely as usable as the previous one. It cannot determine the size of the character array passed to it, nor can it reallocate this array. The only way to specify this function to behave somewhat sensibly is to demand that the argument must be an array of some pre-determined size specified elsewhere. This could only be useful in some pretty narrow contexts.

Note that this is not an immediately obvious observation. The C language used to have gets up until 2011. Programmers used to be rather careless back when.


int get_next_line(int fd, char *line, size_t size);

This could be a somewhat useful function. It could work almost like the standard read function, except it wouldn't read past the first end-of-line character. (Or like fgets for Posix fike handles.) Of course users need to deal with the case of the input line being longer than their array. Presumably get_next_line would return the number if scanned characters.


Note const int is useless in function prototypes. All standard functions specify int in such cases.

n. m. could be an AI
  • 112,515
  • 14
  • 128
  • 243
  • The only quibble would be that the 2nd form is usable *if and only if* `line` has adequate storage before the function call is made. It simply passes a copy of the pointer to `get_next_line` for filling from the descriptor. (this isn't to say it is a preferred form). – David C. Rankin Oct 15 '18 at 17:17
  • @DavidC.Rankin so just like `gets`. It was booted from tge standard in 2011, but you might like the fact that sensible Unix admins started to throw it out of their copies of libc back in 1988 (see "Morris worm"). – n. m. could be an AI Oct 15 '18 at 17:22
  • I'm must be missing something here, because there is no correlation to `gets`. A simple `#define` (the same one used to size storage for `line`) can provide a perfectly valid protection for the bounds of `line` in `get_next_line`. What am I missing? – David C. Rankin Oct 15 '18 at 17:24
  • @DavidC.Rankin So "some pre-determined size specified elsewhere". One needs to provide both `get_next_line` *and* a `#define` together, which requires one to come up with a sensible value for that `#define`d constant. Just like I have said, any such thing "could only be useful in some pretty narrow contexts" (sorry about the abundance of self-quotes). – n. m. could be an AI Oct 15 '18 at 17:33
  • Thank you this seem to help me understand the concept, I will try to simulate this problem to fully understand. – Felix Riddick Oct 15 '18 at 18:14