C “error: function returns address of local variable”

匿名 (未验证) 提交于 2019-12-03 02:11:02

问题:

I'm beginner with C and I am learning on my own. I am creating the following function:

char *foo(int x){      if(x < 0){         char a[1000];         char b = "blah";         x = x - 1;         char *c = foo(x);         strcpy(a, b);         strcat(a, c);         return a;       }     blah ... } 

I am basically trying to return an appended string, but I get the following error:

"error: function returns address of local variable", any suggestions, how to fix this?

回答1:

The local variables have a lifetime which extends only inside the block in which it is defined. The moment he control goes outside the block in which the local variable is defined, the storage for the variable is no more allocated (not guaranteed). Therefore using the memory address of the variable outside the lifetime area of the variable will be undefined behaviour. am, ther

On the other hand you can do the following.

 char *str_to_ret = malloc (sizeof (char) * required_size);   .   .   .  return str_to_ret; 

And use the str_to_ret instead. And when returning str_to_ret, the address allocated by malloc will be returned. The memory allocated by malloc is allocated from the heap, which has a lifetime which spans the entire execution of the program. Therefore you can access the memory location from any block and any time while the program is running.

Also note that, it is a good practice that after you have done with the allocated memory block, free it to save from memory leaks. Once you free the memory, you can't access that block again.



回答2:

This line:

char b = "blah"; 

Is no good - your lvalue needs to be a pointer.

Your code is also in danger of a stack overflow, since your recursion check isn't bounding the decreasing value of x.

Anyway, the actual error message you are getting is because char a is an automatic variable; the moment you return it will cease to exist. You need something other than an automatic variable.



回答3:

PRACTICE:

I am currently teaching a friend of mine the basic concepts of C - and came up with this very simple and straight-forward (i hope so) code example which basically explains everything. Didn't want to hide it from you guys! :)

#include <string.h> #include <stdio.h> #include <stdlib.h>  /* function header definitions */ char* getString();                     //<- with malloc (good practice) char * getStringNoMalloc();  //<- without malloc (fails! don't do this!) void getStringCallByRef(char* reference); //<- callbyref (good practice)  /* the main */ int main(int argc, char*argv[]) {      //######### calling with malloc     char * a = getString();     printf("MALLOC ### a = %s \n", a);      free(a);      //######### calling without malloc     char * b = getStringNoMalloc();     printf("NO MALLOC ### b = %s \n", b); //this doesnt work, question to yourself: WHY?     //HINT: the warning says that a local reference is returned. ??!     //NO free here!      //######### call-by-reference     char c[100];     getStringCallByRef(c);     printf("CALLBYREF ### c = %s \n", c);      return 0; }  //WITH malloc char* getString() {      char * string;     string = malloc(sizeof(char)*100);      strcat(string, "bla");     strcat(string, "/");     strcat(string, "blub");      printf("string : '%s'\n", string);      return string; }  //WITHOUT malloc (watch how it does not work this time) char* getStringNoMalloc() {       char string[100] = {};       strcat(string, "bla");      strcat(string, "/");      strcat(string, "blub");      //INSIDE this function "string" is OK      printf("string : '%s'\n", string);       return string; //but after returning.. it is NULL? :) }  // ..and the call-by-reference way to do it (prefered) void getStringCallByRef(char* reference) {      strcat(reference, "bla");     strcat(reference, "/");     strcat(reference, "blub");     //INSIDE this function "string" is OK     printf("string : '%s'\n", reference);     //OUTSIDE it is also OK because we hand over a reference defined in MAIN     // and not defined in this scope (local), which is destroyed after the function finished } 

When compiling it, you get the [intended] warning:

me@box:~$ gcc -o example.o example.c  example.c: In function ‘getStringNoMalloc’: example.c:58:16: warning: function returns address of local variable [-Wreturn-local-addr]          return string; //but after returning.. it is NULL? :)             ^~~~~~ 

...basically what we are discussing here!

running my example yields this output:

me@box:~$ ./example.o  string : 'bla/blub' MALLOC ### a = bla/blub  string : 'bla/blub' NO MALLOC ### b = (null)  string : 'bla/blub' CALLBYREF ### c = bla/blub  

THEORY:

This has been answered very nicely by User @phoxis. Basically think about it this way: Everything inbetween { and } is local scope, thus by the C-Standard is "undefined" outside. By using malloc you take memory from the HEAP (programm scope) and not from the STACK (function scope) - thus its 'visible' from outside. The second correct way to do it is call-by-reference. Here you define the var inside the parent-scope, thus it is using the STACK (because the parent scope is the main()).

SUMMARY:

3 Ways to do it, One of them false. C is kind of to clumsy to just have a function return a dynamicaly sized String. Either you have to malloc and then free it, or you have to call-by-reference. Or use C++ ;)



回答4:

a is an array local to the function.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. Such variables are also called automatic variabels because their lifetime is automatically managed you do not need to manage it explicitly.

Since you need to extend the variable to persist beyond the scope of the function you You need to allocate a array on heap and return a pointer to it.

char *a = malloc(1000);  

This way the array a resides in memory untill you call a free() on the same address.
Do not forget to do so or you end up with a memory leak.



回答5:

a is defined locally in the function, and can't be used outside the function. If you want to return a char array from the function, you'll need to allocate it dynamically:

char *a = malloc(1000); 

And at some point call free on the returned pointer.

You should also see a warning at this line: char b = "blah";: you're trying to assign a string literal to a char.



回答6:

Neither malloc or call by reference are needed. You can declare a pointer within the function and set it to the string/array you'd like to return.

Using @Gewure's code as the basis:

char *getStringNoMalloc(void){     char string[100] = {};     char *s_ptr = string;      strcat(string, "bla");     strcat(string, "/");     strcat(string, "blub");     //INSIDE this function "string" is OK     printf("string : '%s'\n", string);      return s_ptr;  } 

works perfectly.

With a non-loop version of the code in the original question:

char *foo(int x){         char a[1000];     char *a_ptr = a;     char *b = "blah";             strcpy(a, b);      return a_ptr; } 


回答7:

char b = "blah";  

should be:

char *b = "blah";  


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!