【问题标题】:Check if pointer is null when not initialized [duplicate]检查未初始化时指针是否为空[重复]
【发布时间】:2013-01-21 00:14:49
【问题描述】:

如果变量未初始化,是否可以假设 if 语句始终有效?假设是肯定的,但有人告诉我,变量中的随机垃圾位并不总是意味着检查是否为 null 会起作用。

Void afunction () {
    char* someStr;
    if (someStr) 
    {
        // do something
    }
}

【问题讨论】:

标签: c


【解决方案1】:

如果变量未初始化,是否可以假设 if 语句始终有效?

没有。读取未初始化的存储会调用未定义的行为。你不能对这段代码做出安全的假设。

不要这样做!

【讨论】:

  • 附带说明,在我见过的每个 C/C++ 实现中,这几乎肯定会使用堆栈中的旧值(其他变量的)初始化 someStr。编译器警告您这是有充分理由的。
  • @HevyLight 如果未初始化的变量获得了位于堆栈上的一致旧值,那么您应该认为自己很幸运。优化编译器不会拒绝将未初始化的读取视为不可访问(因为它是未定义的行为)或将变量视为具有多个值。请参阅我在对该问题的评论中发布的两个链接以获取有趣的示例。
  • @HevyLight:情况确实如此。如果您知道自己在做什么,这可能是一种普遍的行为。例如,OpenSSL 使用它作为熵的额外来源。发出的编译器警告使一些不知道自己在做什么的 Debian 维护者删除了“有问题的”代码以及其他一些重要的东西,将 Debian 的 OpenSSL 实现的熵池大小减少到只有 16 位(基于进程 ID)。这被称为 Debian 密码学灾难。
  • “如果你知道你在做什么,这可能是我们的行为”。不!请看kqueue.org/blog/2012/06/25/more-randomness-or-less
  • @PascalCuoq:OpenSSL 使用未初始化内存作为额外熵源的方式比该博文中介绍的要强大得多。如果它是对变量的简单异或,则不会真正提高熵质量。 OpenSSL 所做的是,它将几个熵源的值一个接一个地输入加密哈希函数,将结果位推入反馈移位寄存器。这样做的好处是,如果这样做,熵永远不会缩小。即使编译器优化掉某些部分,它也不会减少已经存在的位
【解决方案2】:

这绝对不能保证总是有效。你必须自己初始化它。

char* someStr = NULL;

或其他一些值。

【讨论】:

    【解决方案3】:

    未初始化的变量是不确定的。在赋值之前读取它们会导致未定义的行为。

    很容易检查指针是否为NULL

    if (someStr) {
       // Don't use it (or do for some weird reason)
    }
    

    为了安全起见并确保指针是您想要的值,我会在初始化时为其分配一个值。

    char* someStr = NULL;
    

    您还可以将指针设为静态以避免未定义的行为。

    static char* someStr;
    

    【讨论】:

    • 我喜欢你的回答,因为它只说“未初始化的变量是不确定的。在分配值之前阅读它们会导致未定义的行为”,但现在您添加了一个我不理解的建议。 if (someStr == NULL)if (someStr) 没有区别。当someStr 未初始化时,你也不应该写。为什么要添加这部分?
    • 对我来说,这是偏好,这确实是唯一的原因。 if 语句用于检查 boolean 值,它们应该是 01,而不是真正用于 NULL 值。这样你就不知道指针实际上是NULL,还是0。如果您愿意,我可以将其编辑回原始版本。
    • 我认为风格偏好*的优先级低于从未初始化指针读取的不确定性,并且问题的答案应该集中在后者上。 * C99 6.8.4.1:2 说“如果表达式比较不等于 0,则执行第一个子语句”,这允许条件表达式是整数、指针,甚至是浮点数。
    • 我会将其还原为原始版本,但 NULL0 具有不同的十六进制表示,这就是我使用特定 if 语句的原因。我相信0 是十六进制的0x30NULL 是十六进制的0x01
    • 6.3.2.3:3 “值为 0 […] 的整数常量表达式称为空指针常量”(此外,该标准允许多个空指针常量,如引号中的“a”,但所有空指针常量必须比较相等 (6.5.9:6))
    【解决方案4】:

    someStr 的值未定义。一般来说,它将被设置为堆栈中的某个旧值。因此,它很可能是 NULL(即 0)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多