局部变量地址可以保留在返回指针的函数中

时间:2013-04-09 13:38:09

标签: c

#include<stdio.h>

int* a(int* b){
 int a = 20;
 printf("\n  \n");
 if(a == 20){
  printf("\n return from if a : 0x%x \n",a);
  return &a;
 }
 else{
  printf("\n returning from else b : 0x%x\n",b);
  return b;
 }
}

int main(){
 int n = 10;
 int *k,*m;
 k = &n;
 m = a(k);
 printf("\n m ; 0x%x m : %d \n",m,*m);
 return 0;
}

这里我返回函数返回指针的局部变量。在函数退出期间,所有变量都将从堆栈内存中移出,但该函数如何仍保留地址'a'的值并打印数据?

o / p:

 return from if a : 0xbfd8cf14

 m ; 0xbfd8cf14 m : 20

地址保留在指针m中,并正确打印该值。我尝试改变不同的号码。

4 个答案:

答案 0 :(得分:6)

这是你的程序调用未定义的行为。可以自由打印任何内容(或崩溃,或做任何想做的事情)。

(也许这就是实际发生的事情:“从记忆中移除”并不意味着持有变量的记忆被破坏,着火或被魔术师消失。这只是它被无效。因为它是函数中的一个自动变量,很可能发生的只是当函数返回时堆栈指针被移动,使变量无效但完好无损。尽管如此,不要依赖它。)

答案 1 :(得分:3)

你可以通过声明static int a = -1;来使返回值“可靠”,即使你从函数返回后也会使a持续存在......但在很多情况下这是一个非常糟糕的主意......特别是如果你要成为多线程的话。

那就是说...返回指向临时(本地)变量的指针会在运行时造成破坏。所以,你永远不想这样做......你需要让它成为一个静态的本地或找到一个更好的方法来处理它。

在您的修改后扩展答案:当您将-1指定为a作为本地变量时,实际上您将-1存储在堆栈上的某个位置并{{1} }指向该位置。当你从函数返回时,堆栈没有被销毁,但是行为现在是未定义的,因为虽然地址是一个有效的指针,但该地址的内容可能已被修改...例如,如果你调用另一个函数,在堆栈上推送数据和/或声明局部变量,它们可能已经覆盖了您期望的值。另外,谁知道优化器可能注入了什么疯狂。所以... 可能 从一个实现到另一个实现。

答案 2 :(得分:3)

退出函数后返回的指针无效。这是一种未定义的行为。

保留的指针指向内存中您无权读取/写入的位置。

要保留有效的地址,请使用static变量。

static int a = -1;
// ...
return &a;

答案 3 :(得分:2)

这是一种未定义的行为。离开函数时,堆栈未被清除,因此变量的实际值仍然存在,但您不应该访问它。在显示变量内容之前尝试调用另一个函数。尝试使用-O3进行编译,以获得可能不同的行为。