读书人

关于地址传递的一个有关问题

发布时间: 2013-01-04 10:04:18 作者: rapoo

关于地址传递的一个问题,求助
本帖最后由 xjiang4 于 2012-11-30 00:13:33 编辑


# include <stdio.h>

void f(int **q)
{
int i=5;
*q=&i;
}

int main(void)
{
int *p;
f(&p);
printf("%d\n",*p);
return 0;
}


此程序使用了地址传递,对一个指针取址,再将其传入被调函数f作参数,不出所料,在vs2010里最终输出结果是5。可是同学问我,在函数f里,指针p被赋值成i的地址,而在main函数里调用函数f结束后,f里的局部变量i应该已经被释放了啊,既然p指向的是同一块区域,怎么还能输出值5呢?
[解决办法]
那是因为这个地址上的内容,暂时没有被刷新覆盖,如此而已。
[解决办法]
这样的用法非常危险,目前结果只是恰好正确而已,因为此时并没有其它代码覆盖其数据,如果程序一大,其中的数据就不可预料了。
[解决办法]
1楼说的不错,栈上的数据没有被其它程序刷新
可以参考下面:

#include <stdio.h>

void f(int **q)
{
int i=5;
*q=&i;
}

void g()
{
int a[20]={0};
}

int main(void)
{
int *p;
f(&p);
printf("%d\n",*p); //5

g();
printf("%d\n",*p); //0
return 0;
}

[解决办法]
你好 在f函数里你的q是一个双重指针 也就是说q本身存放的是main里面p的地址,那么对f函数里的q取*操作就等于对main里的p本身进行操作,所以你在f函数里执行语句*q=&i也就是把i的地址赋值给了main函数中的指针变量p,所以main函数中的p指向个f函数中的i。但是这段代码最致命的缺点就是在f函数执行完之后f函数中的变量被全部释放了,变量i的空间很有可能被别的函数占用。顺便说一下,函数是在栈空间分配空间,栈空间在释放内存时是不会将内存清空的。
[解决办法]
调用子函数A前和调用子函数A后,通常情况,2个栈指针是相同的,在程序中,后续随时都会再调用子函数B,把A原来用的栈空间覆盖掉,所以没必要对调用A后的栈空间清除。

我现在好奇的是为何这样,而不是立即释放呢???
栈没有释放一说,不是堆的动态申请。堆和栈的区别到网上搜下。
栈是随着局部变量的增多而不断增大的,(就是esp ebp指针的不断修改),os并没有专门的结构来管理用户程序使用的栈,再说,os不知道用户程序究竟怎么使用的栈,通俗的说,就是os不知道子函数究竟使用多少临时变量,调用了多少子函数。
[解决办法]
在这个函数里传递的是地址的拷贝,在局部作用域中,该值指向的内存上的内容可以被复写了,碰巧还没被复写,所以显示还是原值。
[解决办法]
因为i的地址内容没有被其他程序覆盖,所以你得到是的值可能是正确的值。
[解决办法]
房租到期后,你继续住在里边,一天两天没问题,可时间长了就有麻烦了。
栈上的空间跟这是同一个道理。

读书人网 >C语言

热点推荐