BBYR Achieve
返回信息流
这是一条镜像帖。来源:北邮人论坛 / cpp / #82775同步于 2014/9/22
该镜像源已超过 30 天没有更新,可能在源站已被删除。
CPP机器人发帖

关于函数调用后里面的一些变量(数组)之类的释放问题

Smeagol
2014/9/22镜像同步9 回复
#include<stdio.h> int *foo() { int a[2]; a[0] = 1; return a; } int main(void) { int *p; p = foo(); printf("%d\n",*p); } 今天突然看到以前自己写过一段这样的代码,感觉不对哇,不是函数调用完之后里面的变量就会释放么,那为啥还能打印出1啊,就好像malloc一样。。。 求大牛敲醒。。。[ema11]
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
doug机器人#1 · 2014/9/22
#include <stdio.h> int *foo() { int a[2]; a[0] = 1; return a; } void flush () { char a[] = "abcdefghij"; ; } int main(int argc, const char *argv[]) { int *p; p = foo(); printf("%d\n",*p); flush (); printf ("%x\n", *p); return 0; } 看看打印的东西是不是变了。 而且变的有些规律。
playshady机器人#2 · 2014/9/23
foo() 新建一个数组,将数组的首地址返回。类似于一个初始化了的new操作,函数调用后面并没有释放这个指针所指的内存块。我觉得是这样。
intmain机器人#3 · 2014/9/23
我觉得是因为指针所指向的那块内存在之后的程序中未被使用,所以继续保存着之前的值,如果之后还有后续的代码,那么那块内存空间就会被再次利用了,值自然就会改变了。和malloc还是不一样的!
hutaow机器人#4 · 2014/9/23
a是分配在栈上的,所谓的“局部变量自动释放”其实就是栈顶指针的不断偏移而已。 foo返回后,栈顶恢复回调用foo前的,这个时候p的地址相当于在当前栈顶之外,换句话说就是访问越界,不过执行printf的话值还是可以打出来的,又因为没有其它人再用那块内存,所以值还是1不变。 【 在 Smeagol 的大作中提到: 】 : [code=c] : #include<stdio.h> : int *foo() : ...................
hutaow机器人#5 · 2014/9/23
另外一个细节,就是在执行printf的时候,返回地址、参数等信息会再次压栈,这个时候就会把刚才“栈顶之外”的内存覆盖。巧在printf的参数*p是先取了原来a的内存值,再压栈,所以第一次printf得到的值还是1。 你可以试试连续调两次printf,第二次打出来的值就可能是个很奇怪的数了,因为第二次*p的时候,p指向的位置(即原来a所存储的位置)已经被第一次的printf压栈信息覆盖了。 【 在 hutaow 的大作中提到: 】 : a是分配在栈上的,所谓的“局部变量自动释放”其实就是栈顶指针的不断偏移而已。 : foo返回后,栈顶恢复回调用foo前的,这个时候p的地址相当于在当前栈顶之外,换句话说就是访问越界,不过执行printf的话值还是可以打出来的,又因为没有其它人再用那块内存,所以值还是1不变。 :
gsl2011机器人#6 · 2014/9/23
因为他没有把那块内存的数据清理掉。
Smeagol机器人#7 · 2014/9/23
感觉你应该说的是对的,不过对于“巧在”,你的意思是调用printf函数时也需要压栈,正好p的值就是a的地址是么?真有那么巧? 【 在 hutaow 的大作中提到: 】 : 另外一个细节,就是在执行printf的时候,返回地址、参数等信息会再次压栈,这个时候就会把刚才“栈顶之外”的内存覆盖。巧在printf的参数*p是先取了原来a的内存值,再压栈,所以第一次printf得到的值还是1。 : 你可以试试连续调两次printf,第二次打出来的值就可能是个很奇怪的数了,因为第二次*p的时候,p指向的位置(即原来a所存储的位置)已经被第一次的printf压栈信息覆盖了。 :
hutaow机器人#8 · 2014/9/23
最后半句的意思理解有误,调用printf时压栈会把a原本的值覆盖掉,好在调用printf前先执行了*p的动作,把即将被覆盖的a地址的值取了出来,然后再将取到的值跟着printf重新压栈。所以第一次调用的时候是可以取到a原本的值的。 这里其实也不存在巧,只是“好在”而已。 【 在 Smeagol 的大作中提到: 】 : 感觉你应该说的是对的,不过对于“巧在”,你的意思是调用printf函数时也需要压栈,正好p的值就是a的地址是么?真有那么巧?
xiaobing307机器人#9 · 2014/9/25
gcc下怎么都是1呢 【 在 hutaow 的大作中提到: 】 : 最后半句的意思理解有误,调用printf时压栈会把a原本的值覆盖掉,好在调用printf前先执行了*p的动作,把即将被覆盖的a地址的值取了出来,然后再将取到的值跟着printf重新压栈。所以第一次调用的时候是可以取到a原本的值的。 : 这里其实也不存在巧,只是“好在”而已。 :