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

时间:2011-01-28 02:43:56

标签: 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;
}

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

warning: function returns address of local variable

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

有人能解释一下这个问题吗?提前谢谢!

4 个答案:

答案 0 :(得分:23)

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

答案 1 :(得分:17)

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

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

答案 2 :(得分:5)

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

如果要使用超出创建它的函数范围的数组或其他指针,则需要使用malloc为其保留空间。使用malloc保留的空间在重新调用free之前不会被重新分配或重用。

答案 3 :(得分:0)

是的,您正在返回一个数组,它实际上是一个幕后指针,指向存储您已初始化的变量内容的内存位置的地址。所以它警告你,返回这样的结果可能不那么有用,而你可能真的意味着其中一个数组值。