在学习指针时,我尝试了指针声明/解除引用。
#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>
int *call() {
int a = 3;
return &a;
}
int main() {
printf("call* is: %d\n", *call());
printf("call is: %p\n", call());
Sleep(2000);
printf("call* is: %d\n", *call());
printf("call is: %p\n", call());
Sleep(2000);
printf("call* is: %d\n", *call());
printf("call is: %p\n", call());
return 0;
}
所以“很明显”“a”是一个局部变量。 但我的问题是, 当我读出“a”的地址时,它始终是相同的地址。 为什么会这样?
PS:我在后台运行一个素数计算器以尽可能多地填充内存,然后我进入“睡眠”以使程序等待,但“a”的地址仍然是同样的。
答案 0 :(得分:3)
a
位于当前线程的堆栈中:每次运行函数call()
时,它在堆栈上“分配”4个字节以存储a
,返回地址然后“释放”它在堆栈上使用的空间(它实际上不是分配/释放任何东西,只是偏移堆栈指针)。
因此,如果连续多次调用它,函数输入的堆栈状态将完全相同,因此堆栈中a
的实际地址每次都相同(请注意)退出该功能后该地址无效)。
您应该执行类似
的操作int * call2(){
int a = 0;
int *b = call();
printf("%d",a);
return b;
}
然后
int *a = call();
int *b = call2();
您会看到a
和b
不同(printf
就是为了确保编译器不会优化任何内容)
由于堆栈是当前线程的本地线程(不受其他进程/线程的影响),因此您的素数计算器和Sleep
根本不可用。
答案 1 :(得分:1)
“call”是返回指向变量的指针吗?这里的问题是“a”不是静态分配的,而是在堆栈上。你现在可以返回它的地址(可能是也可能不是同一个地址,这取决于每次都在同一深度调用“call”),但是不能保证从你返回后该地址指向的地址是什么“呼叫”。你在通话期间放了一个3,当你到处查看那个地址的内容时,可能会被别的东西覆盖。