C/C++中传递动态内存的一些问题

文章中的例子都来自  《程序员面试宝典》(二)。


看书的时候,发现了几个动态内存的问题,很经典,自己在编写程序时也经常要碰到。很多问题,自己也是第一次明白,想了很长时间。


***************题 1 *******************


这是个很经典的问题,回想一下,自己在写程序时也遇到过这种情况,而且错误经常很难发现。

我现在来分析一下错误的地方,我们很多人都觉得这样写没问题,这样也能为str分配一定长度的空间,这正是我们忽略的地方。可能是我们遇到的传指针来交换两个变量的值这样的例子太多,潜意识中总觉得传进去一个指针,就万事大吉了,什么也能帮我们修改了(不管是赋值,还是申请空间……)。这是个很大的问题,这也正是我们容易出错的地方,我们忽略了原来我们传递指针后,操作的都是指针地址所指向的内容,而这道题操作的确实指针本身。这就是错误所在。

这道题毛病出在GetMemory中,函数中的*p实际上是主函数中的str的一个副本,编译器总是要为函数的每个参数制作临时副本。在本例中,p申请了新的内存,只是把p所指的内存地址改变了,但是str丝毫未变。因为函数GetMemory没有返回值,因此str并不指向p所申请的那段内存,所以函数并没有为str申请一段可用的内存。事实上,每执行一次GetMemory就会申请一块内存,但申请的内存却不能有效释放,结果是内存一直被独占,最终造成内存泄漏。

要解决这个问题,可以由于两种方法,

第一种方法还是用指针,这时我们必须采用指向指针的指针:

第二种方法我们可以用函数返回值来传递动态内存:

 

 

***************题 2 *******************

 

很多人看到这个问题时,觉得很简单。认为str是一个函数的局部变量,在函数返回时,它的内存被收回,所以指针指的是个未知区域,容易出问题。这样的返回操作是不允许的。

这样的回答是对的,因为我也是这么回答的。但是先别急,这只是一半,我们其实并没有把它搞得很明白,再来看书上给的一个例子:

相信很多人(包括我)在这就犯嘀咕了。很多人认为这两个题是一样的,考的内容都是同一个,都是局部变量的问题。要是这样理解的话,那就错了。

其实第二个函数是没问题的,这样写就是第一个函数的改进。如果函数写成指针的形式,就不会报错。

这两个例子函数,考察的是我们对局部数组和全局数组的理解。首先我们一定要搞清楚char str[]和char *str的区别:

1、char str[] = “hello word“;是分配一个局部数组。这个局部变量在内存中的栈,共占了11个字节(后面还有一个/n),这个应该都没问题能理解。也就是说字符数组所有的内容全部存在函数所使用的内存中的栈。当函数结束时,这部分栈也随之“丢失“。故str指向了一个空闲区域。

2、而char *str = “hello word“;是分配了一个全局数组。它所对应的是内存中的全局区域。这个局部变量只占了内存的4个字节(也就是指针str所占的内存),这个指针是位于内存的栈中,但是它指向全局区域的一串字符串hello word。所以说,在函数结束时,字符串所占用的内存并不随之“消失“。消失的只是指针所占的内存。

所以,第一个函数要是想修改,可以在语句前,加一个static。通过static开辟一段静态存储空间,使之也变为一个全局区域的数据。

 

 




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值