Инициализация массива C - PullRequest
4 голосов
/ 06 мая 2010

Почему

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"
                           } ;

терпит неудачу с SEGV, когда opcode_str [0] является printf'd?

Я думаю, это потому, что второй листинг не выделил память для пятиэлементного массива указателей, но мне нужно более подробное объяснение.

Всего наилучшего,

Крис.

1 Ответ

10 голосов
/ 06 мая 2010

Это верно. По сути, вы пытаетесь присвоить массив указателю. GCC 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 содержит указатель на DATA. Таким образом (при условии 32-битного) он попытается интерпретировать первые четыре байта в opcode_str ('D', 'A', 'T', 'A') как четыре байта символа *.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...