C array initialisation
Why does
static char *opcode_str[] = { "DATA"
, "DATA_REQUEST_ACK"
, "ACK_TIMER_EXPIRED"
, "ACK_UNEXPECTED_SEQ"
, "ACK_AS_REQUESTED"
} ;
work, but
static char **opcode_str = { "DATA"
, "DATA_REQUEST_ACK"
, "ACK_TIMER_EXPIRED"
, "ACK_UNEXPECTED_SEQ"
, "ACK_AS_REQUESTED"
} ;
fails with SEGV when opcode_str[0] is printf'd?
I think it's because the second listing has not allocated memory for the five element array开发者_开发技巧 of pointers, but I need a more comprehensive explanation.
All the best,
Chris.
That's correct. You're essentially trying to assign an array to a pointer. GCC 4.4.1 warns about this by default:
opcode_str.c:4: warning: initialization from incompatible pointer type
opcode_str.c:5: warning: excess elements in scalar initializer
It repeats the excess elements warning 4 times, since you're essentially putting 5 pointers where only one will fit. You can use gcc -Werror to force all warnings to be errors.
You could do:
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";
But you've already found the best way to do it. As far as when the error occurs, once you invoke undefined behavior you really can't count on a particular time for problems to manifest.
But I think opcode_str holds a pointer to DATA. So (assuming 32-bit) it will try to interpret the first four bytes at opcode_str ('D','A','T','A') as as the four bytes of a char*.
精彩评论