Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C &引用;“可视化”;悬空指针_C_Pointers_Visualization - Fatal编程技术网

C &引用;“可视化”;悬空指针

C &引用;“可视化”;悬空指针,c,pointers,visualization,C,Pointers,Visualization,在学习指针时,我尝试了指针声明/取消引用 #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);

在学习指针时,我尝试了指针声明/取消引用

#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;
}
#包括
#包括
#包括
int*call(){
INTA=3;
回报&a;
}
int main(){
printf(“调用*为:%d\n”,*call());
printf(“调用为:%p\n”,call());
睡眠(2000年);
printf(“调用*为:%d\n”,*call());
printf(“调用为:%p\n”,call());
睡眠(2000年);
printf(“调用*为:%d\n”,*call());
printf(“调用为:%p\n”,call());
返回0;
}
所以“显然”a是一个局部变量。 但我的问题是, 当我读出“a”的地址时,它总是同一个地址。 为什么会这样


PS:我在后台运行一个素数计算器,以尽可能多地填充内存,我输入“Sleep”使程序等待,但“a”的地址始终不变。

调用是返回一个变量指针吗?这里的问题是“a”不是静态分配的,而是在堆栈上。您可以在此时返回其地址(可能是相同的地址,也可能不是相同的地址,这取决于每次是否在相同的深度调用“call”),但一旦您从“call”返回,就无法保证该地址指向什么。在调用过程中,您在其中放入了一个3,当您开始查看该地址的内容时,它可能会被其他内容覆盖。

调用是返回一个指向变量的指针吗?这里的问题是“a”不是静态分配的,而是在堆栈上。您可以在此时返回其地址(可能是相同的地址,也可能不是相同的地址,这取决于每次是否在相同的深度调用“call”),但一旦您从“call”返回,就无法保证该地址指向什么。在调用过程中,您在其中放入了一个3,当您查看该地址的内容时,它可能会被其他内容覆盖。

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
以确保编译器不会优化任何内容)


由于堆栈是当前线程的本地(不受其他进程/线程的影响),因此素数计算器和睡眠根本没有用。

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
以确保编译器不会优化任何内容)


由于堆栈是当前线程的本地线程(不受其他进程/线程的影响),因此素数计算器和睡眠根本没有用。

程序中没有其他线程;你怎么能在后台运行任何东西?你的冰箱也在后台运行吗?好的:)我希望你玩得开心。但是,你能告诉我,我如何“看到”/“想象”a的地址不是常数吗?你几乎所有的假设都是错误的,毫无意义。请首先查阅“未定义的行为”。然后,如果你仍然决定从事这一职业,去看看生成的机器代码,看看发生了什么。进程有自己的虚拟地址空间。在后台运行其他进程(如质数计算器)并不重要。这不会影响测试程序的地址空间;你怎么能在后台运行任何东西?你的冰箱也在后台运行吗?好的:)我希望你玩得开心。但是,你能告诉我,我如何“看到”/“想象”a的地址不是常数吗?你几乎所有的假设都是错误的,毫无意义。请首先查阅“未定义的行为”。然后,如果你仍然决定从事这一职业,去看看生成的机器代码,看看发生了什么。进程有自己的虚拟地址空间。在后台运行其他进程(如质数计算器)并不重要。这不会影响您的测试程序的地址空间。谢谢,我有一些建议在我脑海中引导这一点。谢谢,我有一些建议在我脑海中引导这一点。非常感谢您的努力!我正在慢慢地了解机械师的线索。欢迎光临。一定要仔细阅读。这将帮助你更好地了解正在发生的事情。一旦您对任何答案感到满意,请务必单击复选标记将其标记为已接受。我必须再次感谢您,因为在另一个示例中,我可以检查,当我使用您的代码检查地址时,给定的解决方案一定是错的。非常感谢您的努力!我正在慢慢地了解机械师的线索。欢迎光临。请务必阅读详细的l