错误:函数返回局部变量的地址(error: function returns address of

2019-06-18 03:27发布

我初学C和我学习上我自己的。 我创建了以下功能:

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 ...
}

我基本上是试图返回一个字符串追加,但我得到了以下错误:

“错误:函数返回局部变量的地址”,有什么建议,如何解决这一问题?

Answer 1:

局部变量具有仅延伸在其所定义的块内的生存期。 控制前进了其中本地变量被定义块以外的时刻,该变量的存储是没有更多的分配(不保证)。 因此,使用该变量的存储器地址的变量的生存区域之外将是不确定的行为。

在另一方面,你可以做到以下几点。

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

并使用str_to_ret代替。 当return荷兰国际集团str_to_ret ,根据所分配的地址malloc将被退回。 通过所分配的存储器malloc从堆,其具有寿命横跨程序的整个执行分配。 因此,你可以在程序运行时从任何框图和随时访问的存储位置。

另外请注意,这是一个很好的做法,你已经与分配的内存块完成后, free它从内存泄漏保存。 一旦你释放内存,则无法再次访问该块。



Answer 2:

我想出了这个简单而直接的(我希望如此)的代码示例应该解释本身!

#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
}

当编译它,您将获得[意]警告:

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? :)
            ^~~~~~

......基本上我们在这里讨论!

运行我的例子中得到的输出:

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 

理论:

这已被用户@phoxis回答得很好听。 基本上,想想这样说:其间的一切{}局部范围内,从而由C-标准是“不确定”之外。 通过使用malloc你从HEAP(PROGRAMM范围)内存,而不是从堆栈 (函数范围) -因此,其从外部“可见的”。 做第二个正确的方法是调用-参考 。 在这里,您定义父范围内的变种,因此它被使用堆栈(因为父范围是在main())。

摘要:

3种方式来做到这一点,他们中的一个错误。 C是一种笨拙,只是有一个函数返回一个动态大小的字符串。 要么你要的malloc然后再释放它,或者你必须调用按引用。 或使用C ++)



Answer 3:

需要通过参考既不的malloc或通话。 您可以在函数内声明的指针,并将其设置为字符串/数组,你想退回。

使用@ Gewure的代码为基础:

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; 
}

完美的作品。

随着原题的代码的非循环的版本:

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

    strcpy(a, b);

    return a_ptr;
}


Answer 4:

这条线:

char b = "blah";

没有好 - 你的左值必须是一个指针。

您的代码也是一个堆栈溢出的危险,因为你的递归检查没有边界x的减少值。

无论如何,你所得到的是实际的错误信息是因为char a是一个自动变量; 此刻你return将不复存在。 你需要的不仅仅是一个自动变量以外的东西。



Answer 5:

a是本地函数返回它不存在了,因此你不应该返回一个局部变量的地址function.Once的数组。
换句话说寿命 a是范围内( {}功能的),如果你返回一个指向它你有什么是指针指向一些内存是无效的。 这样的变量也叫自动 variabels,因为他们的寿命自动管理,你不需要明确的管理。

既然你需要扩展变量后仍然保持功能的范围你,你需要分配在堆阵列并返回一个指向它。

char *a = malloc(1000); 

这样,阵列a驻留在内存中,直到您拨打一个free()在同一个地址。
不要忘了这样做,或者你结束了内存泄漏。



Answer 6:

a在功能本地定义的,并且不能被所述功能之外使用。 如果你想返回一个char从功能阵列,你需要动态分配它:

char *a = malloc(1000);

在某些时候拨打free对返回的指针。

你也应该看到,在这条线警告: char b = "blah"; :你想分配字符串文本的char



Answer 7:

char b = "blah"; 

应该:

char *b = "blah"; 


文章来源: error: function returns address of local variable