【问题标题】:How to zero an array of pointers如何将指针数组归零
【发布时间】:2014-03-23 01:56:12
【问题描述】:

我正在为指针数组分配内存。结果有固定数量的项目,我希望所有项目都初始化为NULL

char **result = (char **)calloc(12, sizeof(char *));

我现在可以确定元素result[0]result[11]NULL 吗?

【问题讨论】:

标签: c arrays pointers memory-management


【解决方案1】:

这个问题,IMO,有点夸大了。是的,某些机器在某处绝对不会对 null 使用全位零模式,就像有些机器具有(或历史上具有)奇数字节大小为 9 或 11 位的机器一样。 ) 并且知道这一点有时有助于从另一个不知道这一点的程序员那里赢得免费啤酒,但除此之外也没什么用。 (当然,它对编写 C 标准或编译器的人非常有用。)

我愿意成为这个线程中的几个读者/评论者工作过,或者在类似的机器上运行过;但是你必须明白,stackoverflow 的回答人群在某种程度上偏向于见过并做过这一切的大师类型。 (顺便说一句,我不把自己算在那个群体中..)世界上绝大多数“普通” C 程序员(他们正在编写 C 代码以在常见的 Windows/Mac/Linux/Unix/(* *) 平台,或者编写嵌入式代码以在几乎任何常见的嵌入式架构平台上运行)永远不会在 calloc 不给你有效 NULL指针的系统上工作,并且该死的很少有人会在 unsigned char 不是 8 位宽的机器上工作——而且他们的代码永远不会被移植到其中一个系统的可能性几乎一样大。

因此,尽管我完全同意了解标准的技术细微差别是一件好事——了解更多永远不会有坏处——但我认为您还必须运用一些常识来决定您的代码需要担心哪些类型的可移植性关于。除非您实际上可以访问具有奇怪字节大小或非零位空指针的机器,否则您实际上将无法测试代码的可移植性(更不用说您依赖的任何库了)。条件,并且除非您知道您正在编写的代码需要具有如此广泛的可移植性,否则您最好将精力花在查找和修复系统中更平淡无奇的错误上。

(**) 我是否还需要在此列表中提及 VMS 或被狂热者攻击? :)

【讨论】:

    【解决方案2】:

    这在 C 2011 标准的非规范脚注 296 中明确说明:“请注意,此 [calloc 将所有位初始化为零] 不必与浮点零或空指针常量的表示相同。”

    【讨论】:

      【解决方案3】:

      作为0-通过做指针p的值

      memset(p, 0, sizeof(p));
      

      没必要等于做

      p = NULL;
      

      在每个平台上,您都可以安全行事:

      SomeType ** result = malloc(12 * sizeof(*result));
      if (NULL != result)
      {
        for (size_t i = 0; i < 12; ++i)
        {
          result[i] = NULL;
        }
      }
      

      你可以像这样将它包装在一个宏中:

      #define ALLOCARRAY(result, size) \
        do { \
          result = malloc(size * sizeof(*result)); \
          if (NULL != result) \
          { \
            for (size_t i = 0; i < size; ++i) \
            { \
              result[i] = NULL; \
            } \
          } \
        } while (0)
      

      然后像这样使用宏:

      #include <stdlib.h>
      
      [...]
      
      SomeType ** result = NULL;
      ALLOCARRAY(result, 12);
      if (NULL == result)
      {
        /* Handle error here. */
      }
      else 
      {
        /* Use array here. */
      
        /* Free array. */
        free(result);
      }
      

      【讨论】:

        【解决方案4】:

        calloc() 将分配的空间设置为所有位为零,但在某些实现中空指针可能不是位零。对于可移植的解决方案,您仍然需要手动将它们设置为空指针。

        for (int i = 0; i < 12; i++)
        {
            result[i] = NULL;
        }
        

        【讨论】:

        • s/many/some/。我不认为有很多这样的实现,只有少数。
        • @glglgl 完成。也许大多数时候我听到这个问题的例子,我都专注于例外:)。
        • @glglgl 你在评论中击败了我!除了有效指针值是非零段和零偏移量的偏移量和的旧 8086 内存模型之外,我从未见过非零空指针。还有哪些?嵌入式系统?
        • 正如我在答案下方评论的那样,C FAQ mentions 其中一些。主要是历史的东西......
        • @glglgl 我连一个都说不出来。我需要阅读其中的一些链接。
        猜你喜欢
        • 1970-01-01
        • 2010-11-27
        • 2018-07-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-06-11
        相关资源
        最近更新 更多