이들은 다양한 유형의 소위 "struct hack"이며, comp.lang.c FAQ의 질문 2.6에서 논의되었습니다.
크기가 0 인 배열을 정의하는 것은 사실 C에서는 불법이며 적어도 1989 ANSI 표준 이후였습니다. 일부 컴파일러에서는이를 확장으로 허용하지만,이 옵션을 사용하면 이식 가능하지 않은 코드가 생깁니다.
이 구현하는 더 휴대용 방법은 예를 들어, 길이 1의 배열을 사용하는 것입니다
struct foo {
size_t len;
char str[1];
};
당신은 할당 된 크기를 추적 할 len
를 사용하여 이상 sizeof (struct foo)
바이트를 할당하고 수 str[N]
에 액세스하여 배열의 N 번째 요소를 가져옵니다. C 컴파일러는 일반적으로 배열 범위 검사를 수행하지 않으므로 일반적으로 "작동"합니다. 그러나 엄밀히 말하면 동작은 정의되지 않습니다.
1999 ISO 표준이 사용 대체하기위한 "유연한 배열 구성원"기능 추가 :
struct foo {
size_t len;
char str[];
};
당신은 이전 구조체의 해킹과 같은 방법으로이 다룰 수 있지만 동작은 잘 정의 된. 그러나 당신은 모든 부기를 스스로해야합니다. sizeof (struct foo)
에는 여전히 배열의 크기가 포함되지 않습니다.
struct bar {
size_t len;
char *ptr;
};
을 그리고 이것은 완벽하게 좋은 방법이지만 다른 의미가 있습니다
당신은, 물론, 대신 포인터를 사용할 수 있습니다. "struct hack"이나 유연한 배열 멤버의 가장 큰 장점은 배열이 나머지 구조체와 연속적으로 할당된다는 것입니다. 배열이 memcpy
을 사용하여 구조체와 함께 복사 할 수 있습니다 (대상이 적절하게 할당 됨). 포인터를 사용하면 배열이 별도로 할당됩니다. 원하는 것과 정확히 같을 수도 있고 그렇지 않을 수도 있습니다.
예를 제공해주십시오. – Arafangion
구조체에 관한 설명. C90에서는'lastMemberOfArray []', C99에서는'lastMemberOfArray []', 비표준 GNU에서는'lastMemberOfArray [0]'의 3 가지 경우가 있습니다. C90의 경우 이것은 정의되지 않은 동작에 의존하는 더러운 해킹입니다. 구조체 끝에 패딩 바이트 구조체가 있으면 문제가 발생할 수 있습니다. C99에서는이를 수정하고 _flexible array member_라는 유형을 만들었는데, 이는 동일한 방식으로 작동하지만 잘 정의 된 동작을합니다. 마지막으로, 비표준 GNU는 동일한 목적으로 zero-size 배열을 허용합니다. '-std = c99 -pedantic-errors'를 표준으로 컴파일하면'[0]'은 컴파일되지 않습니다. – Lundin
@ Lundin의 첫 번째 예제는 "lastMemberOfArray [1]'in C90"이어야합니다. 단순한 오타가 기억이 나지 않는 사람들을위한 것입니다. –