代码之家  ›  专栏  ›  技术社区  ›  fadedbee

C数组初始化

  •  4
  • fadedbee  · 技术社区  · 15 年前

    为什么?

    static char *opcode_str[] = { "DATA"
                                , "DATA_REQUEST_ACK"
                                , "ACK_TIMER_EXPIRED"
                                , "ACK_UNEXPECTED_SEQ"
                                , "ACK_AS_REQUESTED"
                                } ;
    

    工作,但是

    static char **opcode_str = { "DATA"
                               , "DATA_REQUEST_ACK"
                               , "ACK_TIMER_EXPIRED"
                               , "ACK_UNEXPECTED_SEQ"
                               , "ACK_AS_REQUESTED"
                               } ;
    

    当opcode_str[0]被打印时,SEGV失败?

    我认为这是因为第二个清单没有为指针的五元素数组分配内存,但是我需要更全面的解释。

    一切顺利,

    克里斯。

    1 回复  |  直到 15 年前
        1
  •  10
  •   Matthew Flaschen    15 年前

    没错。实际上,您正试图为指针分配一个数组。一般合同条款第4.4.1款在默认情况下警告:

    opcode_str.c:4: warning: initialization from incompatible pointer type
    opcode_str.c:5: warning: excess elements in scalar initializer
    

    它重复了4次多余的元素警告,因为你基本上把5个指针放在只有一个适合的地方。您可以使用gcc-werror强制所有警告为错误。

    你可以这样做:

    static char **opcode_str = malloc(sizeof(char *) * 5);
    opcode_str[0] = "DATA";
    opcode_str[1] = "DATA_REQUEST_ACK";
    opcode_str[2] = "ACK_TIMER_EXPIRED";
    opcode_str[3] = "ACK_UNEXPECTED_SEQ";
    opcode_str[4] = "ACK_AS_REQUESTED";
    

    但你已经找到了最好的方法。就错误发生的时间而言,一旦调用未定义的行为,就不能指望在特定的时间出现问题。

    但我认为opcode_str有一个指向数据的指针。因此(假设为32位),它将尝试将opcode_str(“d”、“a”、“t”、“a”)处的前四个字节解释为char*的四个字节。