关闭

malloc(0)

标签: 面试题malloc0C
544人阅读 评论(0) 收藏 举报
分类:

【问题】

下列代码的输出结果是什么:

char *ptr = NULL;
if ((ptr = (char *)malloc(0)) == NULL)
  puts("Got a null pointer\n");
else
  puts("Got a valid pointer\n");














【答案】

  got a Valid pointer


【解析】

①C99的最权威的解释:
    If the size of the space requested is zero, the behavior is implementationdefined:
    either a null pointer is returned, or the behavior is as if the size were some
    nonzero value, except that the returned pointer shall not be used to access an object.

②man malloc:
      If size is 0, then malloc() returns either NULL, or a unique pointer value that can later be successfully passed to free().

③MSDN
     If size is 0, malloc allocates a zero-length item in the heap and returns a valid pointer to that item


【总结】

当调用malloc(0)时,可能返回NULL指针,也可能返回一个有效的指针,这是由编译器的实现决定的。

返回有效指针时,该指针可以被正常free,但是不应该其进程操作。

当malloc分配内存时它除了分配我们指定SIZE的内存块,还会分配额外的内存来存储我们的内存块信息,用于维护该内存块。

因此,malloc(0)返回一个合法的指针并指向存储内存块信息的额外内存,

我们当然可以在该内存上进行读写操作,但是这样做了会破坏该内存块的维护信息,

因此当我们调用free(ptr)时就会出现错误。

首先来解释malloc(0)的问题,这个语法是对的,而且确实也分配了内存,但是内存空间是0,

就是说返回给你的指针是不能用的,感觉奇怪吧?但是从操作系统的原理来解释就不奇怪了,

这要涉及操作系统维护内存的方法来说了,在内存管理中,内存被分为2部分,栈和堆,栈有自己的机器指令,由系统分配,

是一个先进后出的数据结构,malloc分配的内存是堆内存,由于堆没有自己的机器指令,

所以要有系统自己编写算法(库函数)来管理这片内存,通常的做法是用链表,在每片被分配的内存前加个表头,

里面存储了被分配内存的起始地址和大小,你的malloc返回的就是表头里的起始指针,这个地址是由一系列的算法得来了,

通常不会为0,一旦分配成功,就返回一个有效的指针,对于分配0空间来说,算法已经算出可用内存的起始地址,

但是你占用0空间,所以对那个指针操作就是错误的,操作系统一般不知道其终止地址,因为有占用大小就可以推出终止地址,

还有就是即使分配0空间也要释放它,其实是释放的链表结点 。
还有,返回的指针是可用地址的起始地址,虽然你可以无限赋值,但是其实是错误的,

因为可能有其他有用的数据在那一片区域,如果指针越界就会出现意想不到的事情。



0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    文章分类