【问题标题】:calloc(), pointers and all bits zero [duplicate]calloc(),指针和所有位为零[重复]
【发布时间】:2012-10-26 10:24:13
【问题描述】:

可能重复:
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 指针?

【问题讨论】:

  • This 可能感兴趣。
  • 如果没有必要并且没有明显的好处,为什么要在标准化方面过于具体?
  • @ecatmur 虽然链接的问题只问“如果”,但这个问题会问“为什么”。我认为如果删除calloc 和编译器残骸,这个会更好。
  • 可能有一些这样的奇异系统;更好的问题是是否有任何相关系统。我会说答案很可能是否定的。就其价值而言,C 标准允许的许多事物(例如非二进制补码整数)从未 出现在实现中,并且非全零位空指针是就在这种糟糕的程度。
  • @R.. 实际上,补码通常存在于电子秤系统的细分市场中。我怀疑此类系统的许多实现会在内部使用一个补码,但我不知道它们是使用主流 MCU(带有 2 的补码)还是一些自定义解决方案。

标签: c


【解决方案1】:

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

【讨论】:

    【解决方案2】:

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

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

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

    【讨论】:

    • 5.16 也有很多很好的理由。
    • +1 干杯。我从没想过0 可能是一个有效的地址。
    • @hmjd:如果您愿意,它也可以是 Linux 和 OS X 上的有效地址。
    猜你喜欢
    • 2011-12-29
    • 1970-01-01
    • 2014-11-13
    • 1970-01-01
    • 2021-03-17
    • 1970-01-01
    • 2015-02-27
    • 2019-03-23
    • 1970-01-01
    相关资源
    最近更新 更多