2010-08-19 4 views
2

gcc 4.4.3 c89배열의 크기를 할당 초기화

왜 내가 char의 포인터 배열을 초기화 할 때 배열의 크기를 할당 할 수 없는지 궁금합니다. 이 작품을 좋아

variable-sized object may not be initialized 

:

나는 다음과 같은 오류가 발생합니다. 그러나 sizeof는 char *가 4 바이트 크기이므로 4 바이트를 반환합니다. 그게 내가 원하는 실제 크기가 아니기 때문에 좋지 않습니다.

void inc_array(const char * const src, size_t size) 
{ 
    /* Array of pointers */ 
    char *dest[sizeof(src)] = {0}; 
} 

그러나 이것은 실제 크기를 전달하고이를 사용하여 배열의 길이를 초기화하는 것입니다.

sizeof가 size_t를 반환하고 size_t를 전달할 때의 차이점은 무엇입니까? 어떤 제안에 대한

많은 감사,

답변

2

오류 메시지가 말했듯이, 가변 길이 배열을 초기화 할 수 없습니다. 즉, = { 0 } 부분이 문제입니다. 가변 길이 배열을 사용할 수 있습니다. 명시 적으로 초기화하면됩니다.

void inc_array(const char * const src, size_t size) 
{ 
    /* Array of pointers */ 
    size_t i; 
    char *dest[size]; 

    for (i = 0; i < size; i++) 
     dest[i] = 0; 
} 
+0

네, 맞습니다. 나는 단지 그것을 테스트했다. – ant2009

+0

그래서 VLA는 사용자가 시도하고 초기화 할 때만 완벽하게 허용됩니다. 이 오류가 발생한 이유는 이것이 올바른 것으로 표시했습니다. 감사. – ant2009

+0

@robUK : 현재의 C 표준에서 허용되며, 구형 C 표준의 gcc 확장으로 사용할 수 있습니다. – caf

4

사용 malloc 동적 크기의 배열을 할당합니다.

malloc 데이터가 결국 free d가되도록해야합니다.

+0

튜토리얼을 가져 주셔서 감사합니다. 나는 malloc과 free에 대해 알고있다. 그러나, 나는 왜 내가 다음과 같은 char * dest [sizeof (src)]를 할 수 있는지 궁금해서 char * dest [size]를 할 수 없습니까? 감사합니다 – ant2009

+0

@robUK - 편집 내 대답을 참조하십시오 –

+1

@rob : 알 겠어. 'sizeof (src) '가 컴파일 타임에 알려지지 만,'size'는 그렇지 않다. 그것이 문제의 근원입니다. – kbrimington

4

-변수 크기의 배열은 C99 이전를 지원하지 않습니다. 배열 크기는 컴파일 타임 상수가 필요합니다. 원하는 것 :

void inc_array(const char * const src, size_t size) { 
    char ** dest = calloc(size, sizeof(char*)); 
    /* do stuff with dest here! */ 
} 

포인터 배열을 원한다고 확신하지는 않습니다. 나는 다음과 같은 기대했을 것이다 :

void inc_array(const char * const src, size_t size) { 
    char *dest = calloc(size, sizeof(char)); 
    memcpy(&dest[0], &src[0], size); 
    /* do stuff with dest */ 
    free(dest); 
} 

편집 :내가 질문의 두 번째 부분을 답변을 잊어 버렸습니다.

sizeof(src)은 형식의 크기를 계산하기 때문에 컴파일 시간 식 (IIRC)입니다. 이 경우 sizeof(char*)과 동일하며 플랫폼에 따라 32 비트가됩니다. 그러나 size에서 char *dest[size]은 정적으로 결정할 수 없습니다. 둘 다 size_t 값이지만 C89에서는 정적으로 할당 된 배열의 요소 수가 컴파일 타임에 결정 가능해야합니다. 이것이 동적 할당에 의존해야하는 이유입니다.

+1

가변 길이 배열은 * 지원되지 * 않습니다. * 초기화 할 수 없다는 오류가 아닙니다. 분명 OP 컴파일러는 C99를 지원합니다. – caf

+0

gcc의 버전이 GNU 확장으로서 VLA를 지원한다고 생각했습니다. VLA가 C89에서 지원되지 않는다고 간단히 말해야했습니다. 나는 변화를 편집 할 것이다. –

1

당신이 예상하는대로는 sizeof 연산자가 작동하지 않는 이유는 포인터 배열 "붕괴는"당신이 함수에 전달할 때이다 : 이전 버전에서, 당신의 배열을 정의로

int array[5]; 
printf("%d\n", sizeof(array)/sizeof(int)); /* prints 5 */ 

/* ... */ 

void some_function(int array[]) 
{ 
    printf("%d\n", sizeof(array)/sizeof(int)); /* prints 1, no matter what */ 
} 

가변 길이 배열은 허용되지 않았습니다 (Visual Studio는 여전히 C의 이전 버전을 구현합니다).보조 노트로

size_t some_other_size = 5; 
int array3[some_other_size]; /* okay - VLA */ 

의 어떤 버전 : C합니다 (C99 표준을 구현하는 컴파일러)의

const size_t some_size = 22; 
size_t some_other_size = 5; 
int array1[5]; /* okay */ 
int array2[some_size]; /* okay */ 
int array3[some_other_size]; /* not okay - not const */ 

최신 버전은 당신이 변수 크기를 지정할 수 있습니다 : 당신은 일정한 크기를 지정했다 C++ 표준에는 VLA에 대한 지원이 포함되어 있습니다. 그러나 일부 C++ 컴파일러는 자체 확장을 구현했습니다 (Groxx의 설명 참조). kbrimington가 제안

당신이 블라스를 지원하지 않는 C 컴파일러에서 연속 메모리의 변수 금액을 할당 할 경우

, 당신이 malloc을 무료를 사용해야합니다

size_t size = 5; 
int* array = (int*)malloc(sizeof(int) * size); 
/* use array */ 
free(array); 
+0

"C++의 어떤 버전도 VLA를 전혀 허용하지 않았습니다"<- 완전히 부정확합니다. C99, 당신이 언급 한 것입니다. http://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html 또는 http://en.wikipedia.org/wiki/Variable-length_array#Examples (첫 번째 예 참고). GCC에서 컴파일 할 때 몇 가지 물음표가 생겼고 Visual Studio에서 사용하는 모든 것을 교수가 편집하고있었습니다. – Groxx

+0

@Groxx : "C++ 표준의 어떤 버전에도 VLA에 대한 정의가 포함되어 있습니다"라고 다시 말해야 겠지. 그것은 GCC와 IBM의 C++ 컴파일러의 확장판입니다. 그리고 저는 C에 관한 것이지요. C에 관한 문제는 C에 관한 것이지만, 단지 참고 사항입니다. –

관련 문제