【问题标题】:Calloc with structure with pointers in C在 C 中具有带有指针的结构的 Calloc
【发布时间】:2011-08-16 23:41:47
【问题描述】:

我知道 calloc 请求要使用的内存,在所有位上写入 0,然后返回指向它的指针。

我的问题是:如果我将 calloc 与包含指针的结构一起使用,这些指针会具有 NULL 值还是我必须将它们设置为指向 NULL?

struct a{
char * name;
void * p;
}* A;

所以基本上,在我将 calloc 与 struct a 一起使用后,name 和 p 会指向 NULL 吗?

谢谢!

【问题讨论】:

    标签: c pointers null structure calloc


    【解决方案1】:

    不知何故,你得到了很多不正确的答案。 C 不要求空指针的表示为全零位。很多人错误地认为确实如此,因为一个值为 0 的整型常量表达式,转换为一个指针,就变成了一个空指针。

    话虽如此,在所有现实世界的系统上,空指针都是全零位,calloc 是在现实世界中获取空指针初始化的指针数组的完全合理的方法。

    【讨论】:

    • +1:我见过的唯一一个甚至接近正确的答案。我相信一些 IBM 和 Unisys 系统使用空指针,其中并非所有位都为零。就此而言,x86 也可以——段值 0 给出一个空指针,而不管偏移量如何。所有位为零都可以工作,但其他空指针值也是可能的。
    • 仅仅因为一些非零段:偏移指针可以计算为与线性地址零相同,我不会称它为“空指针”。如果您要调用这些空指针,AC 编译器将不得不生成代码来执行昂贵的额外工作来检查空指针,并且它不会提高实现的质量,因为只有编译器创建的表示需要被视为由它生成的代码产生的空指针(空指针永远不会来自算术,只会来自常量表达式)。
    • 实际上我能想到的对空指针使用非全零位的 only 原因是 (1) 如果地址 0 需要可寻址,或者 ( 2)如果您希望空指针取消引用生成陷阱,并且地址 0 不会生成陷阱,但其他地址会生成陷阱。无论硬件如何,都始终有效,使空指针为全零位的 C 实现,因此,没有任何令人信服的理由不这样做,实现者应该始终使用全零-位作为空指针表示。
    • @R。不是这样。这不是评估相同的线性地址的问题。英特尔如何定义保护模式的部分原因是段 0 不能被取消引用(有 no 与其关联的线性地址)。不需要昂贵的额外工作——它只需要检查段部分并忽略偏移量。
    • @R。你可以争论事情应该如何成为你想要的一切——它不会改变事情的本来面目。
    【解决方案2】:

    R. 的回答很好,但我想添加标准引号来支持这一点,并展示一种 0 初始化结构的方法,它实际上会产生 NULL 指针。

    来自N1548(C11 草案)

    7.22.3.2 calloc 函数为 nmemb 对象数组分配空间,每个对象的大小 是大小。空间被初始化为所有位为零。[289]

    脚注接着说(强调):

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

    虽然空指针通常表示为全 0 位,但不能保证这种表示。要直接回答您的问题,您不能依赖 calloc()'d 结构的指针为 NULL


    如果要将动态分配的结构的所有包含的指针设置为NULL,可以使用以下命令:

    struct a *s = malloc(sizeof *s);
    *s = (struct a){0};
    

    C11:

    6.7.9.21 如果大括号括起来的列表中的初始值设定项少于元素或成员的数量 [...] 总量的剩余部分应为 隐式初始化与具有静态存储持续时间的对象相同

    6.7.9.10 ...如果具有静态或线程存储持续时间的对象未初始化 明确地,那么:
    — 如果是指针类型,则初始化为空指针;

    C 要求大括号内至少有一个元素,这就是我使用{0} 而不是{} 的原因。其余元素根据上述规则进行初始化,从而产生空指针。据我所知,这方面的规则在 C11 和 C99 中是相同的。

    【讨论】:

      【解决方案3】:

      callocrequires it to initialize everything to 0 的 ISO C 标准。这意味着,如果您最终将calloc 分配的内存视为指针,它最初确实会包含 NULL (0) 指针。

      【讨论】:

      • “为 0”是不精确的。你的意思是“如果全零位是空指针的表示”。
      猜你喜欢
      • 2021-03-17
      • 1970-01-01
      • 1970-01-01
      • 2013-05-30
      • 1970-01-01
      • 2015-04-10
      • 1970-01-01
      • 1970-01-01
      • 2013-11-18
      相关资源
      最近更新 更多