C语言/C++学习之C语言函数传参:指针的指针
小职 2021-01-13 来源 :IOT物联网小镇 阅读 719 评论 0

摘要:本文主要向大家介绍了C语言/C++学习之C语言函数传参:指针的指针,通过具体的内容向大家展现,希望对大家C语言/C++的学习有所帮助。

本文主要向大家介绍了C语言/C++学习之C语言函数传参:指针的指针,通过具体的内容向大家展现,希望对大家C语言/C++的学习有所帮助。

C语言/C++学习之C语言函数传参:指针的指针

前言

 

今天同事问了一个问题:在函数参数中传递指针的指针,很常用的一个场景,重新梳理一下记录于此,以后如果有类似的问题直接发这篇小总结就可以了。

 

代码:版本1

 

void do_malloc(char *p, int size)

{

    p = (char *)malloc(size + 1);

    memset(p, 0, size + 1);

}

 

 

int main(int argc, char *argv[])

{

    char *pData = 0;

    do_malloc(pData, 128);

    sprintf(pData, "%s", "abc");

    printf(pData);

    return 0;

}

代码本意是:do_work()函数向系统堆空间申请size个字节的空间,然后返回给main函数中的pData指针。但是,执行的时候报错:Segmentation fault (core dumped)。

 

分析原因

 

我们可以把char*类型的指针看成一个遥控器,如果给这个指针赋值,就相当于把这个遥控器与一个设备进行绑定,可以通过遥控器来控制这个设备。

 

执行char *pData = 0;

 

pData内容为空,相当于这个遥控器没有与任何设备绑定,如下图:

 C语言/C++学习之C语言函数传参:指针的指针

 

 

执行do_work(pData, 128);

 

这里传递的参数是pData本身,所以进入void do_work(char *p, int size)函数之后,实参pData的内容就赋值给形参p,所以指针p的内容也为空,也就是说:p这个遥控器也没有与任何设备绑定,如下图:

 C语言/C++学习之C语言函数传参:指针的指针

 

 

执行p = (char *)malloc(size + 1);

 

这句话的作用是把申请到的堆空间的首地址,赋值给p。就是说:现在p指向了内存中的一块空间,就相当于一个p这个遥控器与一个设备进行绑定了,可以控制这个设备了,如下图:

 C语言/C++学习之C语言函数传参:指针的指针

 

 

到这里就已经看到程序崩溃的原因了:虽然给指针p赋值了,但是实参pData中的内容一直为空,因此从do_malloc函数返回之后,pData仍然是一个空指针,所以就崩溃了。当然,p指向的堆空间也就泄露了。

 

代码:版本2

 

代码的本意是在do_malloc函数中申请堆空间,然后把这块空间的首地址赋值给pData。在do_malloc函数中,调用系统函数malloc成功之后返回所分配空间的首地址,关键是要把这个首地址送给pData指针,也就是说要让pData指针变量中的值等于这个堆空间的首地址。

 

那应该如何通过中间的一个函数来完成这个功能呢,如下代码:

 

void do_malloc(char **p, int size)

{

    *p = (char *)malloc(size + 1);

    memset(*p, 0, size + 1);

}

 

 

int main(int argc, char *argv[])

{

    char *pData = 0;

    do_malloc(&pData, 128);

    sprintf(pData, "%s", "abc");

    printf(pData);

    return 0;

}

执行char *pData = 0;

 

这一句没有变化。

 

执行do_malloc(&pData, 128);

 

把pData指针的地址作为实参进行传递,因为pData本身就是一个指针,加上取地址符&,就是指针的指针(二级指针),因此do_malloc函数的第一个参数就要定义成char**类型,此时示意如图:

 C语言/C++学习之C语言函数传参:指针的指针

 

 

p此时是一个二级指针,参数赋值之后,p里面的内容就变成了pData这个指针变量的地址,也就是说p指向了pData这个变量。

 

执行*p = (char *)malloc(size + 1);

 

这句话首先搞明白*p是啥意思,刚才说了,p是一个指针,它指向了pData这个变量。那么在p前面加上取值操作符*,就相当于是取出指针p中的值,它里面的值就是pData!因此,malloc函数返回的堆空间首地址,就相当于是赋值给了pData,如下图:

 C语言/C++学习之C语言函数传参:指针的指针

 

 

此时,pData这个遥控器就与分配的这块堆空间绑定在一起,随后再操作pData就没有问题了。


关注“职坐标在线”(Zhizuobiao_Online)公众号,免费获取学习教程资料、技术就业咨询

C语言/C++学习之C语言函数传参:指针的指针

 


本文由 @小职 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程