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

4 回答 4

32

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

于 2011-01-28T02:49:08.707 回答
25

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

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

于 2011-01-28T02:48:44.120 回答
6

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

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

于 2011-01-28T02:46:11.973 回答
0

是的,您将一个数组(实际上是幕后的指针)返回到存储您已初始化的变量内容的内存位置的地址。所以它警告你,返回这样的结果可能不是很有用,而你可能真的指的是数组值之一。

于 2011-01-28T02:49:12.053 回答