malloc(0)

来源:互联网 发布:svakom 知乎 编辑:程序博客网 时间:2024/05/22 05:30
  1. char *p = (char *)malloc(0);  
  2. strcpy(p, "hello");  
  3. printf("%s/n",p);  
  4. free(p);   

其中,p中的地址是堆内的首地址? 
--------------------------------------------------------------- 

C99标准(ISO/IEC 9899:1999 (E))上说: 

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.

如果所请求的空间大小为0,其行为由库的实现者定义:可以返回空指针,也可以让效果跟申请某个非0大小的空间一样,所不同的是返回的指针不可以被用来访问一个对象。

为什么 new T[0] 和 malloc(0) 不返回空指针

首先需要说明的是,按照C++标准,成功的 new T[0] 是不能返回空指针的。而 malloc(0),C 语言标准则指出,成功的时候可以返回空指针,也可以返回非空指针,多数库一般也选择了返回非空指针这种行为。

为什么这么做呢?
1. 理念:0大小的对象也是对象。
2. 实践:返回空会和分配失败混淆,尤其是大小是计算出来的时候,这时如果得到的是空指针,用户程序会误以为分配失败了。
3. 实现:反正返回的地址不能读写,此时可以返回同一个固定的地址,并没什么额外开销。而且多数编译器,C和C++一起提供,C++库的new也用C库的malloc实现,使二者保持一致也比较省事。
4.不管返回的是不是空,都可以free的。

测试程序如下

view plain
  1. #include <stdlib.h>  
  2. #include <stdio.h>  
  3.   
  4. int main(int argc, char *argv[])  
  5. {  
  6. char *ptr;  
  7. printf("0x%x/n", ptr); // this line will cause seg fault sometimes  
  8.   
  9. printf("----malloc 0 4 times----/n");  
  10. ptr = (char *)malloc(0);  
  11. printf("0x%x/n", ptr);  
  12.   
  13. ptr = (char *)malloc(0);  
  14. printf("0x%x/n", ptr);  
  15.   
  16. ptr = (char *)malloc(0);  
  17. printf("0x%x/n", ptr);  
  18.   
  19. ptr = (char *)malloc(0);  
  20. printf("0x%x/n", ptr);  
  21.   
  22. printf("----malloc 1 4 times----/n");  
  23. ptr = (char *)malloc(1);  
  24. printf("0x%x/n", ptr);  
  25.   
  26. ptr = (char *)malloc(1);  
  27. printf("0x%x/n", ptr);  
  28.   
  29. ptr = (char *)malloc(1);  
  30. printf("0x%x/n", ptr);  
  31.   
  32. ptr = (char *)malloc(1);  
  33. printf("0x%x/n", ptr);  
  34.   
  35. printf("----malloc 4 4 times----/n");  
  36. ptr = (char *)malloc(4);  
  37. printf("0x%x/n", ptr);  
  38.   
  39. ptr = (char *)malloc(4);  
  40. printf("0x%x/n", ptr);  
  41.   
  42. ptr = (char *)malloc(4);  
  43. printf("0x%x/n", ptr);  
  44.   
  45. ptr = (char *)malloc(4);  
  46. printf("0x%x/n", ptr);  
  47.   
  48. printf("----malloc 16 4 times----/n");  
  49. ptr = (char *)malloc(16);  
  50. printf("0x%x/n", ptr);  
  51.   
  52. ptr = (char *)malloc(16);  
  53. printf("0x%x/n", ptr);  
  54.   
  55. ptr = (char *)malloc(16);  
  56. printf("0x%x/n", ptr);  
  57.   
  58. ptr = (char *)malloc(16);  
  59. printf("0x%x/n", ptr);  
  60.   
  61. printf("----malloc 32 4 times----/n");  
  62. ptr = (char *)malloc(32);  
  63. printf("0x%x/n", ptr);  
  64.   
  65. ptr = (char *)malloc(32);  
  66. printf("0x%x/n", ptr);  
  67.   
  68. ptr = (char *)malloc(32);  
  69. printf("0x%x/n", ptr);  
  70.   
  71. ptr = (char *)malloc(32);  
  72. printf("0x%x/n", ptr);  
  73.   
  74. printf("----malloc 64 4 times----/n");  
  75. ptr = (char *)malloc(64);  
  76. printf("0x%x/n", ptr);  
  77.   
  78. ptr = (char *)malloc(64);  
  79. printf("0x%x/n", ptr);  
  80.   
  81. ptr = (char *)malloc(64);  
  82. printf("0x%x/n", ptr);  
  83.   
  84. ptr = (char *)malloc(64);  
  85. printf("0x%x/n", ptr);  
  86.   
  87. return 0;  
  88. }  

系统表现如下:

view plain
  1. root@dell:~/test# ./a.out .  
  2. 0xd27fb840  
  3. ----malloc 0 4 times----  
  4. 0x8060f38  
  5. 0x8060f48  
  6. 0x8060f58  
  7. 0x8060f68    diff=0x10=16B  
  8. ----malloc 1 4 times----  
  9. 0x8060f78  
  10. 0x8060f88  
  11. 0x8060f98  
  12. 0x8060fa8    diff=0x10=16B  
  13. ----malloc 4 4 times----  
  14. 0x8060fb8  
  15. 0x8060fc8  
  16. 0x8060fd8  
  17. 0x8060fe8    diff=0x10=16B  
  18. ----malloc 16 4 times----  
  19. 0x8061340  
  20. 0x8061358  
  21. 0x8061370  
  22. 0x8061388    diff=0x18=24B  
  23. ----malloc 32 4 times----  
  24. 0x8061948  
  25. 0x8061970  
  26. 0x8061998  
  27. 0x80619c0    diff=0x28=40B  
  28. ----malloc 64 4 times----  
  29. 0x8062348  
  30. 0x8062390  
  31. 0x80623d8  
  32. 0x8062420    diff=0x48=72B  

第一个是0xdxxx是因为指针变量在建栈的时候已经在栈上获得4B的一个空间,而空间里面的值,应该是随机的
不过不晓得为什么总指在同一个地方?

malloc在ics(introduction to computer science)中讲过,除了分出来的空间之外,为了维护整个堆结构,并考虑时间,空间效果
其或头,或尾,或头尾,均有额外的指针结构存在
分析16,32,64B的情况可知,多余的部分为8B,猜测是头尾各4B

然后再看,0,1,4的时候都是16B,说明每次分配的时候有个最小下限
也就是起板就是8B作为分出来的数据,另外8B作为额外的指针什么的。