[C, C++] 크기가 0인 배열의 사용 이유 (flexible array member)

크기가 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

Leave a Comment