8

可能的重复:
C 中的 NULL 总是为零吗?

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
  • 长处 5.8,长处 5.10

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

NULLC标准不保证指针全部为零的原因是什么?出于好奇,是否有所有位为零的编译器都不是NULL指针?

4

2 回答 2

10

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

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

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

于 2012-11-06T12:59:34.450 回答
4

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

于 2012-11-06T12:59:22.090 回答