二次指针

#include<isstream>
void GetMemory(char *p,int num)
{
p= (char *)malloc(sizeof(char)*num);
}
int main()
{
char *str=NULL;
GetMemory(str,100);
strcpy(str,"hello");
return 0;
}

结果是什么?都什么意思
运行结果是什么啊?


首先头文件应该包含 
#include<stdlib.h> ,有malloc()的声明 
#include<string.h>,strcpy() 
这个小问题 
这个程序并没有像你想的那样运行,能编译链接,但运行时崩溃 

原因是这样的: 
当传递str给GetMemory()时候: 

首先: 
给形参p开辟一块内存(四字节,指针),这块内存和实参变量所在(不是所指向)的内存是两个独立的内存,没有任何关系,先记住这个,后面会用到,形参num也分配,这个参数不是问题重点,就不多说了 

其次: 
虚实结合,把实参str中内容赋值到形参变量的内存区中(即,把NULL赋值到形参变量的内存中),注意区分内存单元的地址和内存单元中的内容! 

接着: 
用malloc()分配所要的内存区,并将首地址存放在形参内存中,即,形参内存中的内容由原来的NULL变为刚分配内存的首地址,但实参变量所在内存中的内容并没有改变,还是NULL!(因为形参实参变量所在的内存是相互独立的,上面提到了),这是问题的关键 

最后: 
GetMemory()返回,在GetMemory()中形参变量是动态分配,函数返回时,会被自动收回,形参p所在的内存被收回,刚刚存在这里用malloc分配的内存区首地址也随之消失,实参中的内容还是原样(NULL) 

但是到这里程序还正常,没有崩溃,但留下的隐患 
在执行strcpy(str,"hello"); 时候,实际上执行的操作是: 
把字符串常量"hello"拷贝到str指针指向的内存区 
而str指向的内存区地址为NULL(=0),咣当,崩溃! 
这个地址是不允许写的 

另外,如果在void GetMemory(char *p,int num) 
判断p是否为NULL反而弄巧成拙,并不能达到目的,因为对于这个例子传进来的一定是NULL 

你可以在main()中把str打印出来看看
现在这个代码是看不到什么的

解决办法: 
void GetMemory(char **p,int num){*p=(char *)malloc(....);} 
在main()中: 
GetMemory(&str,100); 
或者: 
char * GetMemory(int num){ 
char *p= (char *)malloc(sizeof(char)*num); 
return p; 
} 
在main中: 
str=GetMemory(100); 

对于这个问题需要说明一点: 
malloc()在GetMemory()内部分配了内存,那这部分内存的作用域是不是就是在这个函数体内呢?答案不是的。用malloc分配的内存要用free释放才会收回,所以GetMemory()返回后,malloc()分配的内存并没用释放,所以可以放心使用由malloc()分配的内存。 

对于第二个解决办法中执行return p在后面处理过程是这样的先将p值存入寄存器,然后该函数退出(局部变量p所在内存已经释放)并返回到调用点str=GetMemory(...);把寄存器中的值赋值给str,就是用malloc非配的内存区基址。 

对于这两种解决办法都可以在 
main()中用free(str)释放这块内存。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值