2010-11-23 5 views
4

다음 내용은 무엇을 의미합니까? 크기가 0 인 벡터 선언

struct foo 
{ 
... 
char bar[0]; // Zero size??? 
}; 

나는 나의 동료를 물어 그들은 void* bar를 작성과 동일합니다 내게 말했다.

필자가 아는 한 C 포인터는 단지 4 바이트 변수입니다 (최소한 32 비트 시스템에서는). bar [0]이 포인터 (따라서 4 바이트 길이)임을 컴파일러가 어떻게 알 수 있습니까? 그것은 단지 통사론의 설탕인가?

답변

5

동료가 거짓말했습니다. (아마도 의도적으로 의도적으로 그렇게하지는 않을 것입니다.)

유연한 배열 구성원이라고하며 C99는 char bar[];이고 C89는 char bar[1];이며 일부 컴파일러는 char bar[0];으로 작성하십시오. 기본적으로, 당신은 단지 구조에 대한 포인터를 사용하고, 마지막에 여분의 공간의 양을 모두 할당 :

const size_t i = sizeof("Hello, world!"); 
struct foo *p = malloc(offsetof(struct foo, bar) + i); 
memcpy(p->bar, "Hello, world!", i); 
// initialize other members of p 
printf("%s\n", p->bar); 

그런 식으로, p->bar 저장 크기가 배열 선언에 의해 제한되지 않는 문자열을하지만, 이것은 여전히 ​​struct의 나머지 부분과 동일한 할당으로 이루어지며 (구성원이 char *이어야하고 두 개의 숫자가 malloc이고 두 개의 숫자가 free이어야합니다).

+0

아, 이제 알겠습니다. 이 방법으로 구조 인스턴스는 연속적인 메모리 영역에 포함됩니다. 막대가 포인터이면 다른 메모리 덩어리를 가리 킵니다. 따라서 유연한 배열은 예를 들어 단일 memcopy로 구조를 복사 할 수 있습니다. 리눅스 커널에서 그 구조를 찾았고 사실 하나의 memcopy가 커널 공간에서 사용자 공간으로 복사하는 데 사용되었습니다. – Emiliano

+1

@happy_emi - 하나의'memcpy' (커다란 플러스) 외에도 하나의'malloc' (상대적으로 비쌀 수 있습니다. . –

+0

물론. (btw는 memcpy가 아닌 copy_to_user를 의미합니다.) – Emiliano

0

이것은 컴파일 타임 오류입니다. 동적으로 할당 된 배열 만 0 크기로 할당 할 수 있습니다.

+0

일부 (지연 성) 컴파일러는 C99에서'char bar [];'구문을 표준화하기 전에 사람들이 유연한 배열 구성원을'char bar [0];으로 선언하도록합니다. 그래서 이것은 아마도 오류가 아닙니다. –

0

배열은 포인터를 통해 액세스됩니다 (색인은 암시 적 포인터 임). 그래서 나는 그들이 당신에게 이렇게 말하면 포인터와 같이 해석 될 것이라고 생각합니다. 길이가 0 인 배열이므로 아마도 다음 값을 가리킬 것입니다.

이것은 지식이 아니고 의심스러운 부분입니다. :)

비록 당신이 아무 것도 할 방법이 아니에요 ... 그들이 포인터를 원한다면 그들은 포인터를 사용해야합니다. 왜 그들이 거기에 있는지 말할 수 없다면 안됩니다.

+0

나는 직접 레이블로 생각했다. 그러나 현장은 구조 바닥에 선언되어 있습니다. – Emiliano

3

Chris '대답은 정확하지만 아마 객체를 약간 다르게 할당 할 것입니다.

int n = ...; // number of elements you want 
struct foo *p = malloc(offsetof(struct foo, bar[n])); 

for (int i = 0; i < n; ++i) { 
    p->bar[i] = ...; 
} 

중요한 점은 크리스 '대답은 sizeof(char)==1 때문에 작동한다는 것입니다 그것을 반복하지만, 다른 유형, 당신은 sizeof *bar에 의해 명시 적으로 곱해야 할 것이다.

+0

'offsetof (struct foo, bar [n])'트릭을 먼저 보았던 곳을 잊어 버렸습니다. 그것은 내 버전보다 훨씬 낫다. –

+0

@Chris, 아마도 [Raymond의 블로그] (http://blogs.msdn.com/b/oldnewthing/archive/2004/08/26/220873.aspx)? –

관련 문제