从C中的函数返回局部变量
我认为不允许返回局部变量,但是foo1()工作得很好,返回指向局部对象的指针和对象本身之间似乎有很大的区别从C中的函数返回局部变量,c,pointers,local-variables,C,Pointers,Local Variables,我认为不允许返回局部变量,但是foo1()工作得很好,返回指向局部对象的指针和对象本身之间似乎有很大的区别 有人能解释一下这个问题吗?提前谢谢 任何变量在内存中都有一些空间。指针引用该空间。局部变量所占用的空间在函数调用返回时被释放,这意味着它可以并且将被重新用于其他事情。因此,对该空间的引用最终将指向完全无关的东西。C中的数组是作为指针实现的,因此这最终应用于它们。函数中声明的常量数组也算作局部数组 如果要在创建数组的函数范围之外使用数组或其他指针,则需要使用malloc为其保留空间。使用ma
有人能解释一下这个问题吗?提前谢谢 任何变量在内存中都有一些空间。指针引用该空间。局部变量所占用的空间在函数调用返回时被释放,这意味着它可以并且将被重新用于其他事情。因此,对该空间的引用最终将指向完全无关的东西。C中的数组是作为指针实现的,因此这最终应用于它们。函数中声明的常量数组也算作局部数组 如果要在创建数组的函数范围之外使用数组或其他指针,则需要使用malloc为其保留空间。使用malloc保留的空间在通过调用free显式释放之前不会被重新分配或重用。对于
foo1()
,您将返回局部变量的副本,而不是局部变量本身
对于其他函数,返回指向局部变量的指针的副本。但是,该局部变量在函数完成时被解除分配,因此,如果之后尝试引用它,则会出现严重问题。这里的问题是,当您创建局部变量时,它被分配到堆栈上,因此在函数完成执行后不可用(此处的实现有所不同)。更好的方法是使用
malloc()
保留非本地内存。这里的危险是,您必须取消分配(free()
)您使用malloc()
分配的所有内容,如果您忘记了,就会造成内存泄漏。是的,您返回的是一个数组,实际上是幕后的指针,到存储已初始化变量内容的内存位置的地址。因此,它警告您,返回这样的结果可能不太有用,而您可能实际上是指其中一个数组值。+1。实际上,这意味着您需要在堆上而不是堆栈上分配返回值。您需要在要返回的“数组”上使用malloc或similair。或者最好用一个指向缓冲区+缓冲区长度的指针作为参数。@stefan:是的,这是一个很好的观点。我在答案中添加了更多关于如何解决这个问题的建议。“C中的数组作为指针实现”是一种过度简化;它是上下文可以接受的边界线,但是数组和指针之间有很大的区别(还有很多相似之处)。@Jonathan Leffler:我不知道有什么区别。类型系统对它们的处理是相同的,引用和解引用编译到同一个程序集,无论它是数组引用还是指针。如果您有int*ip,那么*ip和ip[0]是可互换的。*(ip+1)和ip[1]也是如此。这可能是我不知道的,但是数组和指针在C中有什么不同呢;字符b[]=“b”;char*c;字符d[]=“d”代码>。你可以写:c=a代码>和c=b代码>,但不能写入b=a代码>或b=d代码>,这是数组和指针之间的一个重要区别。另一个危险是,如果您不重置(例如,memset
)分配的内存,它可能会从堆栈中泄漏信息。@jweyrich当calloc
方便时,当然是连续分配。@kelloti如果我将局部变量声明为静态并返回它,它仍然不可用吗?@AbdelAleem此时它处于静态生存期领域,因此应该可用。
#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;
}
warning: function returns address of local variable