크기가 0인 배열
크기가 0인 배열을 멤버로 가지는 구조체를 목격했다.
typedef struct st { int data; int arr[0]; }st;
arr[0]이 실제로 0의 크기를 갖는지 확인하기 위해 sizeof로 출력해봤더니 0이 맞다. 어디에 쓰는지 몰라서 인터넷을 뒤졌다.
검색 키워드
크기가 0인 배열은 인터넷에 아래의 키워드들로 검색할 수 있다.
- C Hack
- Struck Hack
- Flexible array member
- Zero length array
이 글은 크기가 0인 배열을 간략히만 소개할 것이므로 자세한 내용은 위 키워드들로 검색이 필요하다.
크기가 0인 배열의 사용 이유
구조체 안의 크기가 0인 배열은 크기가 가변 될 수 있다. 이 점을 활용하여 메모리를 효율적으로 활용할 수 있다.
#include <stdio.h> #include <stdlib.h> #define MAX_SIZE 10 typedef struct st { int data; int arr[0]; }st; int main() { st* test = malloc(sizeof(st) + sizeof(int) * (MAX_SIZE - 1)); int i; for (i = 0; i < MAX_SIZE; i++) { test->arr[i] = i; printf("%d ", test->arr[i]); } return 0; }
위 코드와 같이 배열의 크기를 0으로 선언하고 필요할 때 배열의 원하는 크기만큼 구조체를 동적 할당한다.
arr[0] vs arr[1] vs arr[]
arr[0] 대신에 arr[1]과 arr[]이 있고 같은 목적으로 사용한다. arr[1]은 활용 시 arr[0]과 결과는 같고 내부에서 차이를 보이는 것 같지만 자세히 찾아보지 않았다. 자세히 찾아보지 않은 이유는 arr[]때문이다.
arr[0]은 C언어에서 정식으로 지원하는 표현식이 아니라 사용자들이 일종의 편법으로 사용해오던 것인데 C99부터는 arr[]을 지원하기 시작했다. 따라서 굳이 arr[0]이나 arr[1]을 사용할 필요가 없을 듯하다. arr[0]과 arr[1]이 왜 쓰였는지만 알아두면 될 듯 보인다.
제약조건
테스트를 진행하다가 사용 시 몇 가지 제약조건을 발견했다.
아래 에러 메시지는 GCC컴파일러에서는 출력되지 않았다.
- arr[0]은 구조체의 마지막 멤버변수여야 한다.
- arr[0]은 구조체 밖에 선언될 수 없다.
참고
stackoverflow.com/questions/295027/array-of-zero-length