Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C Returning char[] Warning "returns address of local variable" [duplicate]

This is a portion of a homework assignment.

I am trying to read and return a single line of a file in my method getLine.

char *getLine(FILE *input) {
    char line[30];
    if(fgets(line, sizeof(line), input)!=NULL)
    {
        return line;
    }else{
        return NULL;
    }
}

This would seem to work from what I have been taught regarding pointers, however I am unable to remove the warning message warning: function returns address of local variable [enabled by default]. This warning is referring to the line return line;. My assignment requires that I have no warnings or errors when I compile. I don't see what I am doing wrong.

Most of the help I found suggested malloc-ing space for the line of text, but we haven't covered that in class yet even though I have done some in another class. Is that really the best way to do this? If so, would I be able to free anywhere in the program?

like image 282
haloid2010 Avatar asked Feb 14 '13 10:02

haloid2010


People also ask

How do I fix function returns address of the local variable?

Since the problem is that the return address is actually of a local variable, the solution would be to dynamically allocate memory to a variable to hold the address and pass it to the function as a parameter. Now, the variable is declared outside the function block and is no longer a local variable.

Is it a good programming practice to return address of variable from function to local variable justify your answer with an example program?

Once the function returns it does not exist anymore and hence you should not return the address of a local variable. In other words the lifetime of a is within the scope( { , } ) of the function and if you return a pointer to it what you have is a pointer pointing to some memory which is not valid.

Can we return address of a variable in in function?

We can pass pointers to the function as well as return pointer from a function. But it is not recommended to return the address of a local variable outside the function as it goes out of scope after function returns.

Which section contains local variable function and returns address?

The process stack contains the temporary data such as function parameters, return address and local variables.


2 Answers

char line[30]; is an array with automatic storage duration. Memory where it resides is deallocated once the execution goes out of the scope of your function, thus pointer to this memory that you return becomes invalid (dangling pointer).

Trying to access memory, that has already been deallocated, results in undefined behaviour.

You can allocate your array dynamically and let the caller explicitly deallocate it:

char *getLine() {
    char* line = malloc(30);
    ...
    return line;
}

// somewhere:
char* line = getLine();
...
free(line);
like image 113
LihO Avatar answered Nov 11 '22 21:11

LihO


Alternative without using malloc, not covered by the earlier questions as far as I could find:

/* Warning, this function is not re-entrant. It overwrites result of previous call */
char *getLine(FILE *input) {
    static char line[30];
    return fgets(line, sizeof(line), input);
    /* fgets returns NULL on failure, line on success, no need to test it */
}

Explanation: static variables in function scope retain their values even after function returns. There's just one instance of such a variable, same one is used in every call to that function (so not re-entrant/thread-safe). Memory for static variables is allocated when program starts, it's neither heap nor stack but it's own reserved area in running program's memory space. Value of static variable is initialized just once, before it's first used (above does not have specific initialization, so it's filled with 0, but it could have an initializer too, and that would only be it's value when function is called first time).

While using static variable in this manner may seem a bit hacky (and I agree it is), it's still a valid pattern also employed by standard C for example with strtok() function. It also demonstrates the need for a version which is re-entrant, as C standard also has strtok_r(), which is more complex to use as it has one extra parameter instead of having local static variable in it.

like image 26
hyde Avatar answered Nov 11 '22 22:11

hyde