【问题标题】:In C, why initializing pointer to 0 doesn't give compile time error?在 C 中,为什么将指针初始化为 0 不会产生编译时错误?
【发布时间】:2016-12-13 11:59:03
【问题描述】:

我在玩指针,我试图用一个值而不是内存位置来初始化一个指针变量。

如果我用非零值初始化一个指针,它显然会给我一个编译时错误。

int *p = 1;
main.c:14:14: error: initialization makes pointer from integer without a cast [-Werror=int-conversion]
 int *p = 1;
          ^

但是,如果我将它初始化为值 0,它不会给我一个编译时错误。

int *p = 0; //no compile time error but segmentation fault

为什么会这样?是否有像 0 这样的有效内存地址?通常,地址位置显示为0xffffff 或类似方式。 0如何解释成内存位置?

谢谢

【问题讨论】:

  • 兼容性:0 是历史上定义 NULL 指针的方式
  • 你是如何打印的?
  • printf("%p", (void*)p);打印指针
  • @init 表达式*p 取消引用指针。在空指针上,它会调用未定义的行为。
  • 您是在取消引用它,而不是打印它的价值。并且取消引用无效指针是 UB。

标签: c pointers segmentation-fault


【解决方案1】:

来自 C11 标准(草案):

6.3.2.3 指针

[...]

3 值为 0 的整型常量表达式,或转换为类型的此类表达式 void *,称为空指针常量。如果将空指针常量转换为 指针类型,生成的指针,称为空指针,保证比较不相等 指向任何对象或函数的指针。

【讨论】:

    【解决方案2】:

    通常0 表示“无地址”为NULL。当您以这种方式使用它时,您可以检查:

    if (p) {
         doSomthingWith(*p)
    }
    

    【讨论】:

    • @ohad-eytan 如果 0 是空指针,为什么会出现分段错误?如果我正在打印它,理想情况下不应该显示 (null) 而不是段错误吗?
    • @init 你正在尝试打印p*p?
    • 有时 0 是一个完全有效的地址。
    • @EugeneSh。比如 0x00000 ?
    • @init 不管你怎么写。零就是零。
    【解决方案3】:

    您可以将 0 分配给指针,因为 NULL 通常定义为将 0 转换为 void *。任何其他整数值都是类型不匹配。

    虽然您可以将其他整数值转换为指针以为其分配值,但这样做几乎没有意义,除非您正在处理特定内存位置已知用途的嵌入式环境。

    您收到段错误不是因为您正在打印指针,而是因为您取消引用指针并尝试打印它指向的内容。因为指针有一个NULL 值,所以取消引用它会导致未定义的行为。在这种情况下,它会导致段错误。

    要打印指针,请执行以下操作:

    printf("%p\n", (void *)p);
    

    【讨论】:

      【解决方案4】:

      为什么会这样?是否有像 0 这样的有效内存地址?通常,一个 地址位置显示为 0xffffff 或类似方式。 0 怎么样 解释成内存位置?

      通常,大多数操作系统都无法访问地址 0,因为它们将其保留用于其他任务。

      在 C 中,地址 0 被解释为 NULL 指针,而 NULL 指针被解释为未引用程序可访问的有效内存位置的指针。 因此,如果您定义 int* p = 0int* p = NULL,则用 C 编写的程序假定指针没有指向任何内容(不是 0xffffff 地址)。

      【讨论】:

      • 吹毛求疵:官方表示法是“空指针”,如果将NULL(或只是0)分配给指针变量,则会得到。
      【解决方案5】:

      指针上下文中的文字0 表示空指针常量。 1 始终只是 1,因此是 int

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2023-03-22
        • 2013-02-17
        • 2021-06-23
        • 1970-01-01
        • 1970-01-01
        • 2012-08-23
        • 1970-01-01
        相关资源
        最近更新 更多