#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); } 以上代码片段先猜猜执行结果是多少。 另外,执行完 fun之后,Sleep 1秒,执行结果也不同。 大家分析一下,什么原因? |
|
调用函数之后p就成了野指针了。所以指向的地方变换了,值也就变化了?
|
|
指向地方可能没变,只是指向的地方(也就是地址)保存的数据变化了 |
|
知道什么叫做“结果是未定义”吗?
未定义的代码还去预测?浪费生命! |
|
高手呀,当然不同了
|
|
fun()调用完之后,指针指向的值就没有了吧。*p应该都是NULL吧
|
|
没有实际意义!
|
|
顶无聊的问题。 |
|
int i = 10; 这里定义的变量 i 在出了 void fun() 的作用域之后,由于 i 是在栈上分配的,系统自动回收i 对应的内存。
所以, i 对应的内存已经被释放了, 由于这块内存被释放,所以系统会分配给其他人用。 因此, i 对应的内存已经是别人的东西了,你再去访问,你永远不会知道他的值是谁写进来的。 |
|
求楼上那些说是无聊问题的大神讲解上述现象的原因
要是讲不出来就别装逼了,人家问个问题看把你急的,又没浪费你生命,觉得浪费生命就别回啊,最看不惯这种人 |
|
这里提出这个问题是想让大家分析出现这样结果的原因,借此探究程序堆、栈内存的分配、使用以及回收规则,从而帮助提升代码执行效率。不喜欢这种问题的朋友看看就好。
|
|
大家在新手期都是这么好奇过来的,然后回头去看,这样的好奇是完全地浪费生命而已。
你的那些探究是不会有实际价值的结论了,和你的帮助XXX就更靠不上了。 多尊重别人的经验吧。 |
|
野指针,指哪算哪?哪有什么值。就好比你随手在地图上点了一个地方你知道是那里吗?
|
|
不能指望错误代码得到确定的正确结果。
|
|
10分 |
没执行,不过应该全是10吧,执行fun的时候变量i的内存位置应该跟*p这个形参压进去的位置相同。
执行sleep会变化是因为sleep也是一个函数调用,会压栈,把原来内存位置的东西改写。 debug和release不同是因为,debug版本会加入一些调试信息。 至于gcc,配置一下应该也可以去掉debug信息生成一个release版的 |
10分 |
如果是单线程程序,第一个应该是10,但第二开始应该就不会是10了,而是int类型的随机值了!!
因为保存在栈空间的临时变量i的内存空间已经被重新写如新的数值了! 这个p地址 其实保存了一个栈空间的一个内存地址 这个地址的内容是随时被写人被赋值的 printf后 这个内存地址的内容就被重新写了 |
print参数是传值不是传指针,你把值当指针,得到的数是随机数,弄不好可能程序还会崩溃(访问越界)
|
|
fun 执行完了之后 i 就会被回收掉 p就成野指针了 执行第一次打印的时候会是10 之后就不是了
|
|
没有传指针啊,传的是指针p取值后整形值啊 |
|
分析的有道理,但结果如15楼所描述 结果的确如此! |
|
函数里的局部变量一离开作用域马上被释放,指针所指向的内容成了未定义的了,至于是什么值,得看当时系统在该内存处放了什么东西咯。
|
|
int i是函数内部的。临时变量,函数执行完了,这个就没有意义了。
如果你定义在外面就不会变。 |
|
10分 |
另外,执行完 fun之后,Sleep 1秒,执行结果也不同。
另外,Debug下和Release下结果也不同 另外,Linux下gcc编译结果同VS下Debug结果 =========== 首先,我们都知道,这个已经是野指针了。指针所指向的内存不归你的程序管了。系统可以根据具体情况分配其他人。 所以: 以上只是我个人根据所学推理的。要解释你的情况,应该是要学编译原理的。 |
10分 |
printf(“第1次:*p = %d\n”, *p); 你这个问题是指针指向了栈区的变量!这是错误的,函数返回后,调用了别的函数,别的函数的参数及返回值就会覆盖原来的值,计算式的临时变量也会覆盖原来的值,因此,无法预测你的p指向位置的内容是什么 |
理解和讨论之前请先学会如何观察!
计算机组成原理→DOS命令→汇编语言→C语言(不包括C++)、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言(包括C++)、架构…… 对学习编程者的忠告: VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化,这样过一遍不就啥都明白了吗。 |
|
printf(“第1次:p = %x\n”, p);
你顺带也把p的地址也打印出来看下,你这代码,p指向的地址内容是不确定的,因为i是局部变量,函数退出后指定的内存被回收,p指向的内容不确定。 |
|
#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); } |
|
无知 |
|
全部都是无效值
ps 哪怕输出10 这个10 也是无效值 |
|
其实电脑开机后物理内存的每个字节都是可读写的,从来不会因为所谓的new、delete或malloc、free而被创建、销毁。区别仅在于操作系统内存管理模块在你读写时是否能发现并是否采取相应动作而已。操作系统管理内存的粒度不是字节而是页,一页通常为4KB。
|
|
原因找到了吗?要穷追不舍啊。
|