0

I have the following code:

#include <stdio.h>

char * lookLine (FILE *fichero) 
{
    char p[25];
    fgets (p, sizeof (p), fichero);
    return p;
}

int main (void) {
    printf ("%s\n", lookLine (fopen ("suma.c", "r")));
    return 0;
}

And I get the following output:

#��x�

Not nice. My intention is to print out the first line of the file whose name "suma.c". It should print out the following:

#include <stdio.h>

Nevertheless, if I print out the content of p string into the same lookFile function, it does it fine:

#include <stdio.h>

void lookLine (FILE * fichero) 
{
    char p[25];
    fgets (p, sizeof (p), fichero);
    printf ("%s\n", p);
}

int main (void) {
    lookLine (fopen ("suma.c", "r"));
    return 0;
}

And the output I get now is the correct one:

#include <stdio.h>

My reasoning is this: by using fgets I save the string of the first line of "name.c" in the p array and I return its address, which is taken by the second argument of printf function in main.
But I have found out that this only works when I use the printf function directly into the same lookLine function...

Please, could someone tell me what's really going on here?

Matt
  • 22,721
  • 17
  • 71
  • 112
  • First of all, don't use the name read for a user defined function. That's a standard function in C, which is probably used as lower level function for fread, fget etc. If nothing else, you are confusing the reader, who is going to read your code. – anishsane May 25 '13 at 15:52
  • possible duplicate of [Return char\[\]/string from a function](http://stackoverflow.com/questions/14416759/return-char-string-from-a-function) – user93353 May 25 '13 at 15:53
  • Secondly, I am hoping that this is just a test code. Because this has serious fd leak. – anishsane May 25 '13 at 15:54
  • @anishsane Yes, it's just a test, I tried to do it the simplest possible way. Thank you for the tips about the name of the function, I have changed them. – Daniel Muñoz Parsapoormoghadam May 25 '13 at 16:56

3 Answers3

6

It's because you are returning a pointer to a local array from the read function.

Remember that local variables are stored on the stack, and that includes arrays. And when the function returns that stack space is reclaimed by the compiler to be used by other function calls. So you have a pointer pointing to another function's memory.

Jens
  • 69,818
  • 15
  • 125
  • 179
Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
2

The lifetime of the array p ends at the return statement (technically p is a local variable with automatic storage duration; this means it's lifetime ends at the matching }).

The program then invokes undefined behavior because it uses an indeterminate value (reading from a pointer that no longer points to valid memory). This is the reason you can print the string while still in read(), but get garbage when printing from main().

And note that read is a POSIX function that may be interfering with the one you defined (not a problem in a strict C89 or C99 mode, but most compilers aren't by default). [The OP in the meantime renamed the function to lookLine().]

Jens
  • 69,818
  • 15
  • 125
  • 179
  • Thank you for your answer, it was important to me to know why the hell this was not working. I see that knowing how the stack works is important. I will try to stick to what @Jay says about using the malloc function. – Daniel Muñoz Parsapoormoghadam May 25 '13 at 18:07
1

As pointed to by Joachin Pileborg correctly, you are trying to return a stack variable which will be reclaimed, when you return from the function.

Instead you can try to pass a character array and it's size as inputs to the function read. Btw, if you don't intend to do anything else apart from calling fgets in the read function, then it is better that you call fgets in the main function itself.

Incase if you are doing some additional logic in read and you also cannot pass the buffer and it's size as input to read function, you can allocate the memory required from reading using malloc and return the pointer to the calling function. But, personally, I wouldn't recommend it as it is better to ensure the caller of the read takes the responsibility of creation and deletion of the array.

Jay
  • 24,173
  • 25
  • 93
  • 141