指针动态申请内存的错误分析

 指针动态申请内存的错误有几种解释,

有如下几种:

 

相信我们都知道传值调用参数时,不改变实际参数的值。原理:形参是实参的一个copy(副本),而不是指向同一块内存地址。于是用指针或引用就可以解决这个问题,大多数时候还会节省内存开销,因为不用作副本拷贝。

这样一个例子:

void test(char *ps)
{
ps = (char *)malloc(10*sizeof(char));
}

int main(void)
{
char *str = NULL;

test(str);
strcpy(str, "abcd");
cout << str << endl;
return 0;
}

用指针作为参数,在函数内部申请动态内存,结果该程序会崩溃。

原因其实很简单,ps申请了内存,也就是改变了ps这个副本的内容(即申请的动态内存地址),但函数返回了,原形参ps的内容没有任何改变,就如同上述的传值一样,ps的内容仍为NULL,于是出错。

 

 

 



而且不但出错,该程序还会出现内存泄露的问题,因为malloc的这块内存未释放,也无法释放了。

 

2

试图用指针参数申请动态内存

毛病出在函数getmemory 中.编译器总是要为函数的每个参数制作临时副本,指针

参数p 的副本是 _p,编译器使 _p = p.如果函数体内的程序修改了_p 的内容,就导致

参数p 的内容作相应的修改.这就是指针可以用作输出参数的原因.在本例中,_p 申请

了新的内存,只是把_p 所指的内存地址改变了,但是p 丝毫未变.所以函数getmemory

并不能输出任何东西.事实上,每执行一次getmemory 就会泄露一块内存,因为没有用

free 释放内存.

 

 

感觉上面说的不是很好理解。我把我的理解写一下。

像第二种说法所说,编译器总是要为函数的每个参数制作临时副本,指针

参数p 的副本是 _p,编译器使 _p = p.这就是指针可以用作输出参数的原因.

把这个原因解释一下:

比如你传入一个指针p指向的地址是0xffff,那么复制出来的_p指向的地址也是0xffff,

只不过p和_p本身的存储地址是不一样的。例如p存在内存地址为1的地方,而_P存在地址2这个地方,

但二者指向的内存地址是一致的,所以当修改了_p所指向的地址的内容的时候(也就是修改0xffff,这个地址的内容的时候)

p所指的内存内容也改变了,所以该变的内容就可以传出来了。函数结束_p被删除,但是这不影响p指向内容的修改。

 

 

在申请动态内存这个放面呢,是不一样的。

在函数外p为NULL,

在函数内申请动态内存,相当于_p=(char *)malloc(10*sizeof(char));
这样把新申请的内存地址赋给了_p,比如新申请的内存地址为0xaaaa,那么现在_p所指向的内存地址就是0xaaaa,

但是这不能影响p所指向的地址,因为p和_p是在不同的内存地址存放的,现在只有_p的内容改变了,

也就是说内存地址为2的这块地址的内容发生了改变。

p所指的内存地址仍为NULL.所以不能申请出来动态内存。

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值