一小段运行奇怪的程序

假正经的班长 2015-03-20 05:08:05

#include <stdio.h>

int *p = NULL;

void fun()
{
int i = 10;
p = &i;
}

void main()
{
fun();

printf("第1次:*p = %d\n", *p);
printf("第2次:*p = %d\n", *p);
printf("第3次:*p = %d\n", *p);

}


以上代码片段先猜猜执行结果是多少。
全是无效值?还是全是10?执行一下便知道,但为何如此?



另外,执行完 fun之后,Sleep 1秒,执行结果也不同。
另外,Debug下和Release下结果也不同
另外,Linux下gcc编译结果同VS下Debug结果
……

大家分析一下,什么原因?
...全文
565 30 打赏 收藏 转发到动态 举报
写回复
用AI写文章
30 条回复
切换为时间正序
请发表友善的回复…
发表回复
fcqm8888 2015-05-11
  • 打赏
  • 举报
回复
原因找到了吗?要穷追不舍啊。
赵4老师 2015-03-24
  • 打赏
  • 举报
回复
其实电脑开机后物理内存的每个字节都是可读写的,从来不会因为所谓的new、delete或malloc、free而被创建、销毁。区别仅在于操作系统内存管理模块在你读写时是否能发现并是否采取相应动作而已。操作系统管理内存的粒度不是字节而是页,一页通常为4KB。
lin5161678 2015-03-24
  • 打赏
  • 举报
回复
全部都是无效值 ps 哪怕输出10 这个10 也是无效值
lin5161678 2015-03-24
  • 打赏
  • 举报
回复
引用 9 楼 lwjpker 的回复:
求楼上那些说是无聊问题的大神讲解上述现象的原因 要是讲不出来就别装逼了,人家问个问题看把你急的,又没浪费你生命,觉得浪费生命就别回啊,最看不惯这种人
无知
zhouxiaofeng1021 2015-03-24
  • 打赏
  • 举报
回复
#include <stdio.h> int *p = NULL; void fun() { int i = 10; p = &i; //指向栈内存 } void main() { fun(); printf("第1次:*p = %d\n", *p); 输出栈内存中的数值,但是指针所指向的栈内存,在fun使用后,已经释放 printf("第2次:*p = %d\n", *p);在你这段调用过程中,这段内存,可能被修改,所以数据变动 printf("第3次:*p = %d\n", *p); }
worldy 2015-03-23
  • 打赏
  • 举报
回复
引用 18 楼 cjqpker 的回复:
[quote=引用 16 楼 worldy 的回复:] print参数是传值不是传指针,你把值当指针,得到的数是随机数,弄不好可能程序还会崩溃(访问越界)
没有传指针啊,传的是指针p取值后整形值啊[/quote] printf("第1次:*p = %d\n", *p); 是看错了 你这个问题是指针指向了栈区的变量!这是错误的,函数返回后,调用了别的函数,别的函数的参数及返回值就会覆盖原来的值,计算式的临时变量也会覆盖原来的值,因此,无法预测你的p指向位置的内容是什么
繁重的秋春 2015-03-23
  • 打赏
  • 举报
回复
另外,执行完 fun之后,Sleep 1秒,执行结果也不同。 另外,Debug下和Release下结果也不同 另外,Linux下gcc编译结果同VS下Debug结果 =========== 首先,我们都知道,这个已经是野指针了。指针所指向的内存不归你的程序管了。系统可以根据具体情况分配其他人。 所以: 第一种情况:一秒之内,系统把内存分配其他进程然后又释放掉再分配给另外的进程是可以做到的,而且说不定已经被重新分配很多次了。 第二种情况:Debug下,是可以分辨野指针的。我不清楚编译器是怎么做到的。但是单凭这点,我们就应该知道,debug下分配的内存的方式给release下的应该是不一样的,所以,释放后,结果肯定也是不一样的。 第三种情况:不好理解了。如果是地址一样,值不一样,说明是因为编译器的工作方式一样导致的吧。如果地址和值都一样,可能是计算机本身环境的结果。 以上只是我个人根据所学推理的。要解释你的情况,应该是要学编译原理的。
gw6328 2015-03-23
  • 打赏
  • 举报
回复
int i是函数内部的。临时变量,函数执行完了,这个就没有意义了。 如果你定义在外面就不会变。
蜥蜴枪王 2015-03-23
  • 打赏
  • 举报
回复
函数里的局部变量一离开作用域马上被释放,指针所指向的内容成了未定义的了,至于是什么值,得看当时系统在该内存处放了什么东西咯。
假正经的班长 2015-03-23
  • 打赏
  • 举报
回复
引用 14 楼 windfantsy 的回复:
没执行,不过应该全是10吧,执行fun的时候变量i的内存位置应该跟*p这个形参压进去的位置相同。 执行sleep会变化是因为sleep也是一个函数调用,会压栈,把原来内存位置的东西改写。 debug和release不同是因为,debug版本会加入一些调试信息。 至于gcc,配置一下应该也可以去掉debug信息生成一个release版的
分析的有道理,但结果如15楼所描述
引用 15 楼 tangtangtangbaoli 的回复:
如果是单线程程序,第一个应该是10,但第二开始应该就不会是10了,而是int类型的随机值了!! 因为保存在栈空间的临时变量i的内存空间已经被重新写如新的数值了! 这个p地址 其实保存了一个栈空间的一个内存地址 这个地址的内容是随时被写人被赋值的 printf后 这个内存地址的内容就被重新写了
结果的确如此!
假正经的班长 2015-03-23
  • 打赏
  • 举报
回复
引用 16 楼 worldy 的回复:
print参数是传值不是传指针,你把值当指针,得到的数是随机数,弄不好可能程序还会崩溃(访问越界)
没有传指针啊,传的是指针p取值后整形值啊
狸丶不乖 2015-03-23
  • 打赏
  • 举报
回复
fun 执行完了之后 i 就会被回收掉 p就成野指针了 执行第一次打印的时候会是10 之后就不是了
worldy 2015-03-23
  • 打赏
  • 举报
回复
print参数是传值不是传指针,你把值当指针,得到的数是随机数,弄不好可能程序还会崩溃(访问越界)
tangtangtangbaoli 2015-03-23
  • 打赏
  • 举报
回复
如果是单线程程序,第一个应该是10,但第二开始应该就不会是10了,而是int类型的随机值了!! 因为保存在栈空间的临时变量i的内存空间已经被重新写如新的数值了! 这个p地址 其实保存了一个栈空间的一个内存地址 这个地址的内容是随时被写人被赋值的 printf后 这个内存地址的内容就被重新写了
windfantsy 2015-03-23
  • 打赏
  • 举报
回复
没执行,不过应该全是10吧,执行fun的时候变量i的内存位置应该跟*p这个形参压进去的位置相同。 执行sleep会变化是因为sleep也是一个函数调用,会压栈,把原来内存位置的东西改写。 debug和release不同是因为,debug版本会加入一些调试信息。 至于gcc,配置一下应该也可以去掉debug信息生成一个release版的
孤飞俊驰 2015-03-23
  • 打赏
  • 举报
回复
printf("第1次:p = %x\n", p); 你顺带也把p的地址也打印出来看下,你这代码,p指向的地址内容是不确定的,因为i是局部变量,函数退出后指定的内存被回收,p指向的内容不确定。
赵4老师 2015-03-23
  • 打赏
  • 举报
回复
理解讨论之前请先学会如何观察! 计算机组成原理→DOS命令→汇编语言→C语言(不包括C++)、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言(包括C++)、架构…… 对学习编程者的忠告: 多用小脑和手,少用大脑、眼睛和嘴,会更快地学会编程! 眼过千遍不如手过一遍! 书看千行不如手敲一行! 手敲千行不如单步一行! 单步源代码千行不如单步Debug版对应汇编一行! 单步Debug版对应汇编千行不如单步Release版对应汇编一行! VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化,这样过一遍不就啥都明白了吗。 对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。 (Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)
mujiok2003 2015-03-21
  • 打赏
  • 举报
回复
不能指望错误代码得到确定的正确结果。
  • 打赏
  • 举报
回复
野指针,指哪算哪?哪有什么值。就好比你随手在地图上点了一个地方你知道是那里吗?
taodm 2015-03-20
  • 打赏
  • 举报
回复
大家在新手期都是这么好奇过来的,然后回头去看,这样的好奇是完全地浪费生命而已。 你的那些探究是不会有实际价值的结论了,和你的帮助XXX就更靠不上了。 多尊重别人的经验吧。
引用 10 楼 cjqpker 的回复:
这里提出这个问题是想让大家分析出现这样结果的原因,借此探究程序堆、栈内存的分配、使用以及回收规则,从而帮助提升代码执行效率。不喜欢这种问题的朋友看看就好。
加载更多回复(10)

64,642

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧