#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中,并正确打印该值。我尝试改变不同的号码。
答案 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
进行编译,以获得可能不同的行为。