12-3-23关于一级指针,二级指针

void  myMalloc(char  *s)  //我想在函数中分配内存,再返回  
{  
     s=(char  *)  malloc(100);  
}  
 
void  main()  
{  
     char  *p=NULL;  
     myMalloc(p);    //这里的p实际还是NULL,p的值没有改变,为什么?  
     if(p)  free(p);  
}  
程序2:void  myMalloc(char  **s)  
{  
     *s=(char  *)  malloc(100);  
}  
 
void  main()  
{  
     char  *p=NULL;  
     myMalloc(&p);    //这里的p可以得到正确的值了  
     if(p)  free(p);  

}  

下面我们来深度分析一下:

关于程序1,myMalloc(char *s),当我们在main()中调用该函数时候,编译器会为函数的每个参数制作临时副本(引用除外),因此指针s的副本为_s,编译器则让

_s=s,如果函数体改变了_s所指向的内容,则s所指向的内容也随之改变,这也是指针可以做参数的原因,但是在本例中,_s申请了新的内存,则_s指向了新内存,

换言之,_s本身的指向地址变了,此时s跟_s所指向的是不同的内存地址,这样s所指向的内容一直没变,每调用该函数一次,会再堆上申请一块内存,长期这样会

导致内存泄露,后果是很严重的。

那么myMalloc(char **s)为什么又是可行的呢,道理是一样的,这是一个二级指针,编译器同样会复制该二级指针_s,由上面的分析过程,一级指针所指向的地址变了,

但是我们二级指针_s与s所指向的一级指针都没发生变化,变的是一级指针指向的内存,这样_s,s都可以通过该一级指针找到那块内存。这样可以达到我们的要求


补充一句,如果真想利用一级指针申请动态内存,可以改动该函数的返回值,即可。


下面我们再来看一个返回栈指针的例子。:

程序3:char  *GetString(void)  
{  
           char  p[]  =  "hello  world";  
           return  p;            //  编译器将提出警告  
}  
void  Test4(void)  
{  
char  *str  =  NULL;  
str  =  GetString();            //  str  的内容是垃圾  
cout<<  str  <<  endl;  
}  
程序4:char  *GetString2(void)  
{  
           char  *p  =  "hello  world";  
           return  p;  
}  
void  Test5(void)  
{  
           char  *str  =  NULL;  
           str  =  GetString2();  
           cout<<  str  <<  endl;  
}  
程序3返回的是栈内存的指针,一旦函数执行完毕,该指针也就是漂浮指针了。但是为什么程序4能够达到我们的要求,因为char *p="hello world",这里是在静态存储区域

申请的一块内存,在程序运行的过程中,一直存在,但是有个缺陷就是他是个只读的区域块。



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值