3
#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

4 回答 4

6

这是您的程序调用未定义的行为。它可以免费打印任何东西(或崩溃,或做任何它想做的事)。

(也许这就是实际发生的情况:“从内存中删除”并不意味着保存变量的内存被破坏,着火或被魔术师消失。只是它失效了。因为它是一个自动变量在一个函数中,很可能发生的事情只是函数返回时堆栈指针发生了移位,使变量无效但完好无损。不过,不要依赖这个。)

于 2013-04-09T13:39:03.880 回答
3

static int a = -1;您可以通过声明即使在您从函数返回后仍然保持返回值来使返回值“可靠” a......但在许多情况下这是一个非常糟糕的主意......特别是如果你将是多线程的。

也就是说......返回指向临时(局部)变量的指针将在运行时造成严重破坏。因此,您永远都不想这样做……您需要将其设为静态本地或找到更好的方法来处理它。

编辑后扩展答案:当您分配-1a局部变量时,您实际上存储-1在堆栈上的某个位置并&a指向该位置。当您从函数返回时,堆栈不会被破坏,但行为现在未定义,因为虽然地址是有效指针,但该地址处的内容很可能已被修改......例如,如果您调用另一个函数将数据推送到堆栈和/或声明局部变量,它们很可能已经覆盖了您期望的值。此外,谁知道优化器可能注入了什么疯狂。所以......它可能会工作,如果您碰巧在其他任何东西与它混淆之前读取了该值......但是您不能保证它会起作用,而且它通常会因一种实现而异。

于 2013-04-09T13:40:35.577 回答
3

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

保留的指针指向内存中您不再有权对其进行读/写的位置。

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

static int a = -1;
// ...
return &a;
于 2013-04-09T13:40:50.700 回答
2

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

于 2013-04-09T13:40:10.403 回答