从C中的函数返回局部变量

Mar*_*ark 34 c pointers local-variables

#include <stdio.h>

int foo1(void)
{
    int p;
    p = 99;
    return p;
}

char *foo2(void)
{
    char buffer[] = "test_123";
    return buffer;
}

int *foo3(void)
{
    int t[3] = {1,2,3};
    return t;
}

int main(void)
{
    int *p;
    char *s;

    printf("foo1: %d\n", foo1());
    printf("foo2: %s\n", foo2());
    printf("foo3: %d, %d, %d\n", p[0], p[1], p[2]);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

当我编译它时gcc -ansi -pedantic -W -Wall,编译器会发出foo2()和foo3()的警告消息:

warning: function returns address of local variable
Run Code Online (Sandbox Code Playgroud)

我认为不允许返回局部变量,但foo1()工作正常,似乎返回指向本地对象的指针和对象本身之间存在巨大差异.

任何人都能对这个问题有所了解吗?提前致谢!

kel*_*oti 25

这里的问题是,当你创建局部变量时,它会在堆栈上分配,因此一旦函数完成执行就不可用(这里的实现会有所不同).最好的方法是使用malloc()保留非本地内存.这里的危险是你必须释放(free())你分配的所有东西malloc(),如果你忘记了,你就会造成内存泄漏.

  • 另一个危险是如果你不重置(例如`memset`)分配的内存,它可能会从堆栈中泄漏信息。 (2认同)
  • @AbdelAleem 此时它处于静态生命周期领域,所以它应该可用。 (2认同)

小智 19

对于foo1(),您返回局部变量的副本,而不是局部变量本身.

对于其他函数,将返回指向局部变量的指针的副本.但是,当函数完成时,该局部变量将被释放,因此如果您之后尝试引用它,最终会出现令人讨厌的问题.


Kei*_*win 5

任何变量在内存中都有一些空间.指针引用该空间.当函数调用返回时,局部变量占用的空间被释放,这意味着它可以并且将被重用于其他事物.因此,对该空间的引用将最终指向一些完全不相关的东西.C中的数组实现为指针,因此最终应用于它们.在函数中声明的常量数组也算作本地数组.

如果要使用超出创建它的函数范围的数组或其他指针,则需要使用malloc为其保留空间.使用malloc保留的空间在通过免费调用显式释放之前不会被重新分配或重用.

  • +1.在practive中,这意味着您需要在堆上而不是在堆栈上分配返回值.您需要在要返回的"数组"上使用malloc或similair.或者更好的是,将指针指向缓冲区+缓冲区长度作为参数. (3认同)