Chinaunix首页 | 论坛 | 博客
  • 博客访问: 130722
  • 博文数量: 21
  • 博客积分: 850
  • 博客等级: 准尉
  • 技术积分: 146
  • 用 户 组: 普通用户
  • 注册时间: 2010-04-26 20:50
文章分类
文章存档

2011年(4)

2010年(17)

我的朋友

分类: C/C++

2010-08-28 21:18:58


转载  malloc(0)返回什么地址? 收藏

问题内容:malloc(0)返回什么地址?

  • 原讨论链接:
  • 所属论坛: 审核组:
  • 提问者: 解决者:
  • 感谢:
  • 关键字:
  • 答案:

    char *p = (char *)malloc(0);
    strcpy(p, "hello");
    printf("%s\n",p);
    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的。

    测试程序如下

    #include
    #include

    int main(int argc, char *argv[])
    {
    char *ptr;
    printf("0x%x\n", ptr); // this line will cause seg fault sometimes

    printf("----malloc 0 4 times----\n");
    ptr = (char *)malloc(0);
    printf("0x%x\n", ptr);

    ptr = (char *)malloc(0);
    printf("0x%x\n", ptr);

    ptr = (char *)malloc(0);
    printf("0x%x\n", ptr);

    ptr = (char *)malloc(0);
    printf("0x%x\n", ptr);

    printf("----malloc 1 4 times----\n");
    ptr = (char *)malloc(1);
    printf("0x%x\n", ptr);

    ptr = (char *)malloc(1);
    printf("0x%x\n", ptr);

    ptr = (char *)malloc(1);
    printf("0x%x\n", ptr);

    ptr = (char *)malloc(1);
    printf("0x%x\n", ptr);

    printf("----malloc 4 4 times----\n");
    ptr = (char *)malloc(4);
    printf("0x%x\n", ptr);

    ptr = (char *)malloc(4);
    printf("0x%x\n", ptr);

    ptr = (char *)malloc(4);
    printf("0x%x\n", ptr);

    ptr = (char *)malloc(4);
    printf("0x%x\n", ptr);

    printf("----malloc 16 4 times----\n");
    ptr = (char *)malloc(16);
    printf("0x%x\n", ptr);

    ptr = (char *)malloc(16);
    printf("0x%x\n", ptr);

    ptr = (char *)malloc(16);
    printf("0x%x\n", ptr);

    ptr = (char *)malloc(16);
    printf("0x%x\n", ptr);

    printf("----malloc 32 4 times----\n");
    ptr = (char *)malloc(32);
    printf("0x%x\n", ptr);

    ptr = (char *)malloc(32);
    printf("0x%x\n", ptr);

    ptr = (char *)malloc(32);
    printf("0x%x\n", ptr);

    ptr = (char *)malloc(32);
    printf("0x%x\n", ptr);

    printf("----malloc 64 4 times----\n");
    ptr = (char *)malloc(64);
    printf("0x%x\n", ptr);

    ptr = (char *)malloc(64);
    printf("0x%x\n", ptr);

    ptr = (char *)malloc(64);
    printf("0x%x\n", ptr);

    ptr = (char *)malloc(64);
    printf("0x%x\n", ptr);

    return 0;
    }

    系统表现如下:
    # ./a.out .
    0xd27fb840
    ----malloc 0 4 times----
    0x8060f38
    0x8060f48
    0x8060f58
    0x8060f68    diff=0x10=16B
    ----malloc 1 4 times----
    0x8060f78
    0x8060f88
    0x8060f98
    0x8060fa8    diff=0x10=16B
    ----malloc 4 4 times----
    0x8060fb8
    0x8060fc8
    0x8060fd8
    0x8060fe8    diff=0x10=16B
    ----malloc 16 4 times----
    0x8061340
    0x8061358
    0x8061370
    0x8061388    diff=0x18=24B
    ----malloc 32 4 times----
    0x8061948
    0x8061970
    0x8061998
    0x80619c0    diff=0x28=40B
    ----malloc 64 4 times----
    0x8062348
    0x8062390
    0x80623d8
    0x8062420    diff=0x48=72B

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

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

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


  • 阅读(1369) | 评论(0) | 转发(0) |
    给主人留下些什么吧!~~