calloc(),指针和所有位零

时间:2012-11-06 12:53:50

标签: c

  

可能重复:
  Is NULL always zero in C?

C标准规定了calloc()的以下内容:

  

calloc函数为nmemb对象数组分配空间,每个对象的大小都是size。空间初始化为所有位零。

以下警告与所有位零

有关
  

请注意,这不一定与浮点零或空指针常量的表示相同。

测试程序:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int main()
{
    char** list = calloc(10, sizeof(*list));
    int i;
    for (i = 0; i < 10; i++)
    {
        printf("%p is-null=%d\n", list[i], NULL == list[i]);
    }
    free(list);

    return 0;
}

我用以下编译器构建并执行了这个程序:

  • VC7,VC8,VC9,VC10
  • gcc v4.1.2,gcc v4.3.4
  • Forte 5.8,Forte 5.10

在所有情况下所有位零是一个NULL指针(除非我在测试程序中犯了错误)。

C标准不能保证NULL指针所有位为零的原因是什么?出于好奇,有没有所有位为零的编译器不是NULL指针?

2 个答案:

答案 0 :(得分:10)

com.lang.c FAQquestion 5.16中回答了这个问题,它解释了为什么会发生这种情况,question 5.17,它提供了非零NULL的实际机器示例。相对“常见”的情况是地址0有效,因此为NULL选择了不同的无效地址。一个更为深奥的例子是Symbolics Lisp机器,它甚至没有我们所知的指针。

因此,选择正确的编译器并不是一个真正的问题。在具有或不具有虚拟内存的现代字节可寻址系统上,您不太可能遇到不是地址0的NULL指针。

C标准经过精心设计,可以容纳奇怪的硬件,这只是结果之一。另一个奇怪的问题是,sizeof(void *) != sizeof(int *)可能是{{1}},但你永远不会在字节可寻址架构上看到它。

答案 1 :(得分:4)

是的,有一些实现(其中一些是exotics),其中NULL指针的内部表示不是全位零。 C FAQ的这一部分非常有趣(特别是这些部分:12)。