In general, the problem is as follows:

#include <sys/types.h> #include <stdio.h> #include <assert.h> #include <errno.h> char buf[5]; int main(int argc, char **argv) { ssize_t len = 0; char *buffer=buf; //buffer = realloc(buffer,10); FILE *f = fopen(argv[1],"r"); ssize_t a = getline(&buffer, &len, f); printf("%zd", a); fclose(f); return 0; } 

when calling the library function getline and passing the pointer to it not on the heap, the function works in normal mode and without errors. If we use our own implementation of getline (more precisely, honestly copied getdelim, for example, with getdelim , then we catch the error:

* Error in `./a.out ': realloc (): invalid pointer: 0x080497ed * Aborted

It is clear that the problem is in realloc and passing it a pointer. But can anyone know how to get around this?

  • If you just want to use getline (), then @Harry gave the answer. Or is the question in the header still interesting (for example, do you want to hack the same getline)? (specify @ my-nickname in the answer, otherwise the notification will not reach me) - avp
  • @avp I just want to understand why the standard getline does not fall when the pointer to the allocated memory is passed to it. How is it implemented? - brunbash
  • It looks 1) at buffer and if it is 0, it mallocs and puts the size in len 2) at len ​​and if the next character does not fit in the buffer, it does realloc, changing buffer and len. If in buffer a pointer to the memory allocated by malloc, then everything is OK. If the memory in the stack or static, then realloc falls (this address does not correspond to the structure of the blocks of dynamic memory). In 2 words, if something else is not clear, specify, try to tell in more detail. - avp

2 answers 2

Another answer is because it is an answer to a completely different question :)

So - asked in the comments:

How to determine where memory is allocated, which suppose we were transferred to the index? or is it impossible? The implementation, which is provided by reference - does not work, it checks whether the memory is enough and if not, then it increases it via realloc. But if you use the Linux implementation of global memory problems, there is no.

We take the implementation of the GCC library, for example, from here . Open getline :

 getline (lineptr, linelen, fp) char** lineptr; size_t* linelen; FILE* fp; { return _IO_getdelim (lineptr, linelen, '\n', fp); } 

We are looking for the implementation of _IO_getdelim , and, as I expected , we find in it the following after the introductory steps:

 if (*lineptr == NULL || *n == 0) { *n = 120; *lineptr = (char*) malloc(*n); if (*lineptr == NULL) { result = -1; goto unlock_return; } } 

So, if you pass in the parameter of length 0, then the function assumes that there is no buffer, and allocates it again using malloc !

Try calling getline in your code correctly.

 char buf[5]; int main(int argc, char **argv) { ssize_t len = 5; // !!!!!!!!!!!!!!!!! char *buffer=buf; FILE *f = fopen(argv[1],"r"); ssize_t a = getline(&buffer, &len, f); printf("%zd", a); fclose(f); return 0; } 

and look at the results ...

    As far as I know from man-a by getline , for example, then either you give it the address of a null pointer and the address of an integer value 0 :), or a non-zero pointer and its size, but a non-zero pointer to the memory obtained by calling malloc .

    And you transfer a non-zero pointer to global data, and zero length. And what do you want from her? Most likely, everything will fly by on the first realloc .

    Get around?

    Option 1:

     ssize_t len = 0; char *buffer= NULL; ssize_t a = getline(&buffer, &len, f); 

    Option 2:

     ssize_t len = k; // Сами решите, чему оно равно char *buffer= malloc(k); ssize_t a = getline(&buffer, &len, f); 

    If I'm not mistaken, then so ...

    PS Your link, by the way, something is not working ...

    • strange link works for me. several different getline sources were used, they are all almost identical. I know the essence of the function. I’m wondering why it doesn’t break when you transfer an unallocated memory to it. How is it implemented? - brunbash
    • So this is a completely different question - this is a question about the internal structure of getline . We need specific sources here. As I understand, those that are by reference do not work. So what kind of code interests you? Consider, by the way, that different compilers and even different versions may have different implementations. - Harry
    • I am interested in the following - how to determine where the memory is allocated, which suppose we were transferred to the index? or is it impossible? The implementation, which is provided by reference - does not work, it checks whether the memory is enough and if not, then it increases it via realloc. But if you use the Linux implementation of global memory problems, there is no - brunbash
    • Frankly, it is hard to believe that there is a version that goes this way - figuring out where the memory is located. I believe more that when she sees the transmitted zero as length, she simply allocates a new memory, and does not perform realloc ... - Harry
    • See my second answer. My guesses were correct ... Does not check getline , where the buffer is located. And is it even possible? Is that some very bad, unusual, dirty hack ... - Harry