当前位置: 首页 > 科技观察

C语言函数参数传递:指向指针的指针

时间:2023-03-14 14:34:16 科技观察

前言今天同事问了一个问题:函数参数中传递指向指针的指针是很常见的场景,在这里重新整理记录一下,如果大家有类似的问题在以后直接发这个小总结就够了。代码:版本1voiddo_malloc(char*p,intsize){p=(char*)malloc(size+1);memset(p,0,size+1);}intmain(intargc,char*argv[]){char*pData=0;do_malloc(pData,128);sprintf(pData,"%s","abc");printf(pData);return0;}原代码为:do_work()函数申请sizebytesfrom系统堆空间空间,然后在main函数中返回pData指针。但是执行的时候报错:Segmentationfault(coredumped)。分析原因,我们可以把char*类型的指针看成一个遥控器。如果给这个指针赋值,就相当于把遥控器绑定到一个设备上,就可以通过遥控器控制这个设备了。执行char*pData=0;pData的内容为空,表示遥控器没有绑定任何设备,如下图所示:Executedo_work(pData,128);这里传递的参数是pData本身,所以进入voiddo_work(char*p,intsize)函数,将实参pData的内容赋值给形参p,所以指针p的内容也为空,即也就是说:遥控器p没有绑定任何设备,如下图:executep=(char*)malloc(size+1);这句话的作用是将申请的堆空间的首地址赋值给p。也就是说:现在p指向内存中的一个空间,相当于一个p,遥控器绑定了一个设备,可以控制设备,如下图:已经可以看出原因了程序在这里崩溃的原因:虽然指针p被赋值了,但是实参pData中的内容一直为空,所以从do_malloc函数返回后,pData还是空指针,所以崩溃了。当然p指向的堆空间也泄露了。代码:2版代码的初衷是在do_malloc函数中申请堆空间,然后将这块空间的首地址赋值给pData。在do_malloc函数中,调用系统函数malloc成功后,返回分配空间的首地址。关键是把这个首地址传给pData指针,也就是说让pData指针变量中的值等于堆空间的首地址。那么如何通过中间的一个函数来完成这个功能,如下代码:voiddo_malloc(char**p,intsize){*p=(char*)malloc(size+1);memset(*p,0,size+1);}intmain(intargc,char*argv[]){char*pData=0;do_malloc(&pData,128);sprintf(pData,"%s","abc");printf(pData);return0;}执行字符*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没问题。本文转载自微信公众号“IOT物联网小镇”,可通过以下二维码关注。转载本文请联系物联小镇公众号。刀哥