我最近在C中读到了范围规则。它表示本地或自动变量仅在声明它的函数块内可用。一旦在功能之外,它就不再可见了。此外,它的生命周期直到函数体的最终结束括号结束。
现在问题就在于此。当局部变量的地址从函数返回到调用函数时会发生什么?
例如: -
main()
{
int *p=fun();
}
int * fun()
{
int localvar=0;
return (&localvar);
}
一旦控件从函数fun返回,变量localvar就不再存活了。那么main将如何访问此地址的内容?
答案 0 :(得分:3)
可以返回地址,但无法可靠地读取存储在地址中的值。实际上,你甚至不能清楚地分配它,尽管在大多数机器上可能没有问题。
您经常可以阅读该地址,但行为未定义(请阅读' 错误:要不惜一切代价避免!')。特别是,地址可以用于其他函数中的其他变量,因此如果在调用其他函数后访问它,则肯定不会通过返回指针的函数看到变量中存储的最后一个值。
为什么函数会返回一个需要的指针?
一个原因通常是“动态记忆”。 malloc()
函数系列返回指向新(非堆栈)内存的指针。
另一个原因是'在这个位置发现了一些传递给我的东西'。考虑strchr()
或strstr()
。
另一个原因是'返回指向静态对象的指针,隐藏在函数中或包含函数源的文件中'。考虑asctime()
等(并担心线程安全)。
可能还有其他一些,但这些可能是最常见的。
请注意,这些都不会返回指向本地(基于堆栈的)变量的指针。
答案 1 :(得分:0)
在函数返回后在内存中引用该位置是危险的。当然,该位置仍然存在(并且它可能仍然包含您的值),但您不再对该内存区域有任何声明,并且随着程序的继续并且在堆栈上分配新的局部变量,它可能会被新数据覆盖。
gcc
给了我以下警告:
t.c: In function ‘test’:
t.c:3:2: warning: function returns address of local variable [enabled by default]
考虑这个测试程序:
int * test(int p) {
int loc = p;
return &loc;
}
int main(void) {
int *c = test(4);
test(5);
printf("%d\n", *c);
return 0;
}
你认为这会印刷什么?
答案 2 :(得分:0)
变量消失了,但内存位置仍然存在,甚至可能仍包含您设置的值。然而,当调用更多函数并且内存地址被重用于另一个函数的局部变量时,它可能会被快速覆盖。您可以通过阅读Call Stack来了解更多信息,这是存储函数局部变量的地方。