通过函数分配内存,理解实参,形参之间的传递.

    技术2022-05-11  89

           在csdn上遇到一个问题,通过阅读大家对问题的解答,解除了自己多年的一个疑惑,实参,形参之间的传递问题. 该问题如下:  void getbuf(char *p,int num){ p=(char*)malloc(sizeof(char)*num); }int main(){  char *pstr=NULL;  getbuf(pstr,10);  strcat(pstr,"hello");return 0;} 上面这块代码有问题吗   仔细分析上面的代码,出问题的地方有两处: 1.getbuf函数作用是通过参数传递获得分配的内存.但此处的传递不能获得分配的内存,并且造成了内存泄漏. 2.主程序内,没有对新分配的内存进行判断,初始化,释放操作.容易造成内存操作错误,赋值不准确,内存泄漏.         首先,谈谈这段代码的运行过程,这里引用网友 HouJinkun2005(岱瀛) 的分析: 是这样的,你首先声明了变量char *pstr;pstr 在内存中本身就有一个位置,他占了4个字节的空间,假设他的地址为0x1000;然后你pstr=null;则表明了你0x1000里面放的这四个字节的内容是全0. 然后你调用了函数getbuf(pstr,10); 这个时候,首先是两个形参分配了空间,(char *p,int num)假设 p的地址是 0x3000, num的地址是0x3004.  (注意了,p和pstr并不是同个位置) 然后,把pstr里的值全0放到p里面.把10的值放到num里面. (这个时候p和pstr值相同,位置不同) p=(char*)malloc(sizeof(char)*num); malloc函数分配了一块内存空间,然后把首地址放到p里面,假设是0x40000.这个时候*p就是0x4000.但是*pstr还是全0 函数退出,局部变量和参数的空间都被出栈,就是说p这个变量不见了,0x3000,0x3004这些都没有了。但是0x40000这块地址还是存在,内存泄露. *pstr依然等于0.没有达到你要的效果。         其次,谈谈行参与实参的传递过程. 通常有三种说法:传值,传引用,传指针..其实都可以理解为传值,只是另外两个是特殊的值.函数调用时,先将实参入栈,然后创建形参,获得实参的一个副本,操作完毕后(如果形参是实参的指针或者引用,可通过改变形参指向的值来达到改变实参指向的值),最后实参出栈(实参的值从头到尾都未发生变化,但其指向的值可能发生了变化).这里可以引用网友sarh2onacy() 的话: 个人理解,无所谓传值,传指针和传引用。参数传递的实质都是传值。我们只是为了把指针和引用这两种特别的变量与普通变量区分开,才总结出三种传参方式。我们知道要改变实参的值,就要传实参的指针。其中原理就不再赘述。同理:要改变指针的值,就要传指针的指针(也就是二维指针)。很显然楼主要改变的是一个指针的值,所以应该传这个指针的指针给函数,即可。         最后,说说程序的健壮性问题.上面的程序如果改写成正确内存分配函数后,,那么还需要考虑几个问题:第一:分配后的内存为空判断.虽然函数正确了,但不避免由于操作系统自身或其他问题造成内存分配失败,这里判断是否为空,相当于进行了异常处理;第二:需要对新分配的内存进行初始化,防止新分配的内存内存在垃圾数据;第三:释放分配的内存.C/C++程序没有垃圾回收机制,需要内牢记,谁申请就要谁释放,这样才可能避免内存泄漏.            正确的程序可以引用LeoDiao(Leo Diao)的程序: /***test1_8.c  * 测试'S http://community.csdn.net/Expert/topic/5317/5317330.xml?temp=9.965152E-02* 参考:http://community.csdn.net/Expert/topic/5317/5317330.xml?temp=9.965152E-02*Enviroment: Win xp sp2 + Dev-C++4.9.2.2 + --std c99*/#include<stdio.h>#include<conio.h>#include<string.h>#include<stdlib.h> char* getbuf(int num); int main(){ char *pstr=NULL; pstr = getbuf(10); memset(pstr, 0, 10); strcat(pstr,"hello"); printf("%s/n",pstr); free(pstr); system("PAUSE"); return EXIT_SUCCESS;}/***********************Purpose:*      *Entry:*       *Exit:*      **********************/char* getbuf(int num){ return (char*)malloc(sizeof(char)*num);}  

    最新回复(0)