在学习指针时,我尝试了指针声明/解除引用。
#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:我在后台运行一个素数计算器来填充尽可能多的内存,我放入“ sleep ”以使程序等待,但“a”的地址仍然总是一样的。
最佳答案
a
位于当前线程的堆栈上:每次运行函数 call()
时,它都会在堆栈上“分配”4 个字节给 stock 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
根本没有用。
关于c - 悬空指针"Visualization",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21022925/