指针学习小计

前两天看到一个讲函数调用的帖子:http://blog.chinaunix.net/uid-23069658-id-3981406.html。突然想到以前自己犯过的一个错误,虽然现在不再犯了,但总觉得自己仍有理解不到位的地方,如下函数:

void fun(int *ps)

{
ps = (int *)malloc(sizeof(int));
}
void main()
{
int *p;
fun(p);
*p = 1;

}

这函数当然是错的,但突然要我很详细地讲解错点,恐怕逻辑上不能理顺,今天用一种最简洁的方法描述:key在于定义一个指针其实栈上已经给其分配4字节空间,用于保存地址,如果再malloc,则会在堆上再给其分配4字节,同时会修改栈上数据为堆的起始地址,所以一个分配完内存的整型指针所占用的空间为4个栈+4个堆。记住一点:任何时候定义的变量所占据的栈都是不一样的。

        上述代码定义p时为其分了4个栈,里面是随机值,定义ps时为其分配4个栈,里面的值等于入参p,两个栈里的数据相同(*p==*ps),但两者栈地址不一样,当为ps进行malloc操作成功后,会修改ps对应栈里的数据变为malloc出来的堆的地址,对于p对应栈里的数据没有任何修改,所以当函数执行完走到*p=1这一步时,会报地址写入冲突错误。


void fun(int **ps)

{
*ps = (int *)malloc(sizeof(int));
}
void main()
{
int *p;
fun(&p);
*p = 1;

}

函数修改如上后,p的栈位置与栈内数据同上,ps定义时会分配4个栈,存在ps=&p,即表示ps的栈数据(*ps)与&p的站内数据(*(&p),即p)相同,此时调用malloc为*ps分配堆并修改其栈内数据,即等同于修改p的栈内数据,于是p的栈内数据成功变为malloc出来的堆地址。

fun函数内:


fun函数结束,走到*p=1处:



《C与指针》都看到山沟里了,想想第一次看这本书还是7年前,可惜忘了很多,现在看来到了翻出来回味的时候了。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值