Chinaunix首页 | 论坛 | 博客
  • 博客访问: 4520586
  • 博文数量: 1148
  • 博客积分: 25453
  • 博客等级: 上将
  • 技术积分: 11949
  • 用 户 组: 普通用户
  • 注册时间: 2010-05-06 21:14
文章分类

全部博文(1148)

文章存档

2012年(15)

2011年(1078)

2010年(58)

分类: C/C++

2011-09-22 15:27:48

http://blog.csdn.net/han_348154920/article/details/5949877

ANSI C的,如果认为malloc(0)是语法错误的话,下面我写的就不用看了。
下面进入正题,关于malloc(0)这个问题,我在网上看到有个面试题好像就是问这个的,原题好像是:
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空间也要释放它,其实是释放的链表结点

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


http://blog.sina.com.cn/s/blog_7740e1160100rtv5.html

特例  char *ptr; //ptr  0Xcccccccc错误指针  if ((ptr = (char *)malloc(0)) == NULL)// ptr指向一个合法地址  puts("Got a null pointer");  else  puts("Got a valid pointer");  此时得到的是Got a valid pointer。把0赋给malloc能得到一个合法的指针。
阅读(1570) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~