C中的范围规则

时间:2011-12-10 03:43:17

标签: c

我最近在C中读到了范围规则。它表示本地或自动变量仅在声明它的函数块内可用。一旦在功能之外,它就不再可见了。此外,它的生命周期直到函数体的最终结束括号结束。

现在问题就在于此。当局部变量的地址从函数返回到调用函数时会发生什么?

例如: -

 main()
 {
     int *p=fun();
 }

 int * fun()
 { 
     int  localvar=0;
     return (&localvar);
 }

一旦控件从函数fun返回,变量localvar就不再存活了。那么main将如何访问此地址的内容?

3 个答案:

答案 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来了解更多信息,这是存储函数局部变量的地方。