2010-05-06 4 views
4

이유C 배열 초기화

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 실패 하는가?

두 번째 목록은 포인터의 다섯 요소 배열에 대한 메모리를 할당하지 않았기 때문에 생각합니다. 그러나 더 포괄적 인 설명이 필요합니다.

모두 최고,

Chris.

답변

10

맞습니다. 포인터를 배열에 할당하려고합니다. GCC 4.4.1은 기본적으로 이것에 대해 경고 :

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

그것은 당신이 본질적으로 하나가 맞는 5 포인터를 옮기고 있기 때문에, 4 번 경고를 초과하는 요소를 반복합니다. 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')에서 처음 4 바이트를 char *의 4 바이트로 해석하려고 시도합니다.

+0

감사합니다. 왜 컴파일시 또는 포인터가 초기화 될 때 실패하지 않습니까? – fadedbee

+2

@Chrisdew는 C의 의미 규칙을 위반하는 정의되지 않은 동작입니다. 위반하는 규칙은 * 스칼라의 이니셜 라이저는 단일 표현식이어야하며 선택적으로 중괄호로 묶어야합니다. * 여러 표현식은 중괄호로 묶여 있습니다. –

+1

그게 다예요, 경고를 내 화면에서 바로 울리게하겠습니다. 도! 이제 char * 포인터를 "DATA"포인터의 값으로 설정하는 것을 볼 수 있습니다. "DATA"는 마치이 4/8 바이트가 포인터를 가지고있는 것처럼 평가되어 segfault가 발생했습니다. – fadedbee