这是我的代码
#include<stdio.h>
int * fun(int a1,int b)
{
int a[2];
a[0]=a1;
a[1]=b;
//int c=5;
printf("%x\n",&a[0]);
return a;
}
int main()
{
int *r=fun(3,5);
printf("%d\n",r[0]);
printf("%d\n",r[0]);
}
我在Windows 7上运行代码块 每次运行循环时,我都会将输出作为
22fee8
3
2293700
以下是我不理解的部分:
r需要一个指向内存部分的指针,该指针在调用有趣函数时被解释为一系列框(每个4字节宽度的框 - >整数)
应该发生的是printf of function将打印[0]的地址或地址:
借调
现在的问题是:
每次运行程序时,我都会得到相同的地址吗?
并且在函数调用结束时应该销毁数组a只有函数调用后才能保留指针 那么为什么地球r [0]必须打印3?
答案 0 :(得分:2)
指向不再存在的东西。您正在返回指向堆栈上某些内容的指针。当fun()结束时,该堆栈将倒带。它之后可以指向任何东西,但没有任何东西覆盖它,因为永远不会调用另一个函数。
答案 1 :(得分:1)
没有任何东西强迫r[0]
为3 - 这只是寻求最简单的可接受行为的结果。
基本上,你必须在a
结束时销毁fun
。所有这些意味着返回的指针(在您的情况下为r
)完全不可靠。也就是说,即使您的特定计算机上使用特定编译器的r[0] == 3
,也无法保证每台计算机都能保留这一点。
要理解为什么它如此一致,请考虑一下:a
被摧毁的意义是什么?只有你不能以任何可靠的方式使用它。满足这个简单要求的最简单方法是使堆栈指针移回到调用fun
的点。因此,当您使用r[0]
时,a
的值仍然存在,但它们是垃圾数据 - 您不能指望它们存在。
答案 2 :(得分:1)
这就是:
int a[2];
分配在堆栈(或类似)上。假设它在地址0x12345678的堆栈处分配。a
分配的内存不再有效。现在,两个int值仍然位于RAM中的给定地址,包含分配给它们的值。但是堆栈指针不是保留那些单元格,程序中的任何其他东西也不跟踪那些数据。计算机不会通过删除值等来删除数据,它们会通过忘记在内存位置存储任何使用内容来删除单元格。答案 3 :(得分:0)
r
的堆栈被释放后, int * fun(int a1,int b)
未定义,在它结束后,它可以是3或42或任何值。它仍然包含您的预期值的事实是因为它没有被用于其他任何东西,因为您的内存的一大块是为您的程序保留的,并且您的程序不会进一步使用堆栈。然后在打印前3后,你得到另一个值,这意味着堆栈被用于其他东西,你可以归咎于printf()
,因为它是唯一运行的东西,它做了很多事情让这些数字进入控制台
为什么它总是打印相同的结果?因为你总是做同样的过程,所以没有任何魔力。但是不能保证它不会是3,因为“记忆空间”不是你的,而你只是“窥视”它。
此外,检查编译器的fun()
和main()
的优化级别,如果要优化二进制文件,减少“随机性”,可以内联或替换它们。在你的结果中预期。虽然我不希望它改变太多。
答案 4 :(得分:0)
你可以在这里找到很好的答案:
Though the examples are for C++, underlying idea is same.