#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()工作正常,似乎返回指向本地对象的指针与对象本身之间存在巨大差异。
有人能解释一下这个问题吗?提前谢谢!
答案 0 :(得分:23)
这里的问题是,当你创建局部变量时,它会在堆栈上分配,因此一旦函数完成执行就不可用(这里的实现会有所不同)。最好的方法是使用malloc()
来保留非本地内存。这里的危险是你必须释放(free()
)你使用malloc()
分配的所有东西,如果你忘记了,你就会造成内存泄漏。
答案 1 :(得分:17)
对于foo1()
,您返回局部变量的副本,而不是局部变量本身。
对于其他函数,返回指向局部变量的指针的副本。但是,当函数完成时,该局部变量将被释放,因此如果您之后尝试引用它,最终会出现令人讨厌的问题。
答案 2 :(得分:5)
任何变量在内存中都有一些空间。指针引用该空间。当函数调用返回时,局部变量占用的空间被释放,这意味着它可以并且将被重用于其他事物。因此,对该空间的引用将最终指向一些完全不相关的东西。 C中的数组实现为指针,因此最终应用于它们。在函数中声明的常量数组也算作本地数据。
如果要使用超出创建它的函数范围的数组或其他指针,则需要使用malloc为其保留空间。使用malloc保留的空间在重新调用free之前不会被重新分配或重用。
答案 3 :(得分:0)
是的,您正在返回一个数组,它实际上是一个幕后指针,指向存储您已初始化的变量内容的内存位置的地址。所以它警告你,返回这样的结果可能不那么有用,而你可能真的意味着其中一个数组值。