大橙子网站建设,新征程启航
为企业提供网站建设、域名注册、服务器等服务
这篇文章主要介绍“如何理解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内容为空,相当于这个遥控器没有与任何设备绑定,如下图:
执行do_work(pData, 128);
这里传递的参数是pData本身,所以进入void do_work(char *p, int size)函数之后,实参pData的内容就赋值给形参p,所以指针p的内容也为空,也就是说:p这个遥控器也没有与任何设备绑定,如下图:
执行p = (char *)malloc(size + 1);
这句话的作用是把申请到的堆空间的首地址,赋值给p。就是说:现在p指向了内存中的一块空间,就相当于一个p这个遥控器与一个设备进行绑定了,可以控制这个设备了,如下图:
到这里就已经看到程序崩溃的原因了:虽然给指针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**类型,此时示意如图:
p此时是一个二级指针,参数赋值之后,p里面的内容就变成了pData这个指针变量的地址,也就是说p指向了pData这个变量。
执行*p = (char *)malloc(size + 1);
这句话首先搞明白*p是啥意思,刚才说了,p是一个指针,它指向了pData这个变量。那么在p前面加上取值操作符*,就相当于是取出指针p中的值,它里面的值就是pData!因此,malloc函数返回的堆空间首地址,就相当于是赋值给了pData,如下图:
此时,pData这个遥控器就与分配的这块堆空间绑定在一起,随后再操作pData就没有问题了。
到此,关于“如何理解C语言函数传参:指针的指针”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注创新互联网站,小编会继续努力为大家带来更多实用的文章!