注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

尐鬼じ☆ve伱

和你在一起的日子

 
 
 

日志

 
 

malloc(0)问题 (转)  

2012-04-17 15:13:08|  分类: C/C++ |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

http://blog.chinaunix.net/uid-25147458-id-2978421.html

char *ptr;
if ((ptr = (char *)malloc(0)) == NULL)
puts("Got a null pointer");
else
puts("Got a valid pointer");
该代码的输出是“Got a valid pointer”,不信的可以尝试下!只给出答案,但没给出具体的原理解答。

下面我说一下关于这个题目的尝试情况:
正常在指针的引用时候,如果定义char *str = NULL;后如果不对其进行malloc的话,执行memcpy(str,"hello",strlen("hello"))是会出现错误的,而且malloc的空间必须要大于等于strlen("hello")。正常的malloc一个大于0的长度,会在堆区分配一段空间来供程序员使用,memcpy等等。理论上来说如果想要赋值一个字符串到目标指针执行的空间,这个指针指向的空间必须有足够的“大小”来存储。按照malloc(a)函数的说明,malloc错误会返回一个NULL指针,如果执行成功会返回一个大小为a的空间,malloc(0)如果可以成功执行,则应该在堆区分配一个大小为0的空间,但我尝试往这个空间赋值,会发现无论你要复制的字符串有多长都可以复制进去,和正常的malloc(strlne(str))这样不同的是这个空间无法通过free来释放掉,free(str)就会报错。

 

解答:

首先来解释malloc(0)的问题,这个语法是对的,而且确实也分配了内存,但是内存空间是0,就是说返回给你的指针是不能用的,感觉奇怪吧?但是从操作系统的原理来解释就不奇怪了,这要涉及操作系统维护内存的方法来说了,在内存管理中,内存被分为2部分,栈和堆,栈有自己的机器指令,是一个先进后出的数据结构,我就在这里不再过多解释了,malloc分配的内存是堆内存,由于堆没有自己的机器指令,所以要有系统自己编写算法来管理这片内存,通常的做法是用链表,在每片被分配的内存前加个表头,里面存储了被分配内存的起始地址和大小,你的malloc返回的就是表头里的起始指针,这个地址是由一系列的算法得来了,通常不会为0,一旦分配成功,就返回一个有效的指针,对于分配0空间来说,算法已经算出可用内存的起始地址,但是你占用0空间,所以对那个指针操作就是错误的,操作系统一般不知道其终止地址,因为有占用大小就可以推出终止地址,还有就是即使分配0空间也要释放它,其实是释放的链表结点

还有,返回的指针是可用地址的起始地址,虽然你可以无限赋值,但是其实是错误的,因为可能有其他有用的数据在那一片区域,如果指针越界就会出现意想不到的事情。

  评论这张
 
阅读(106)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017