본문 바로가기
Programming/C

가변길이 구조체에 대하여... (flexible array member)

by jjayheony 2025. 6. 26.
반응형

네트워크 통신 중에 동적할당 되는 구조체를 만들었고

data 를 header 와 body 로 나눈 뒤 body 에도 동적으로 데이터를 받아왔다.

그러다보니 header 의 메모리 영역과 body 의 메모리 영역이 다르기 때문에 내가 만들어 놓은 recv 함수로는 header 와 body 를 동시에 처리할 수 없었다. 따라서 header 일 때 recv 호출과 body 일때 recv 호출, 즉 2번의 호출을 해야했다.

다른 방법이 있는 지 알아보다가 가변길이 구조체까지 얼핏 듣게 되었다.

 

[가변길이 구조체 선언방법]

struct test {
  int a;
  int b;
  char c[];
};

struct test1 {
  char c[];
  int a;
  int b;
};

struct test2 {
  int a;
  char c[];
  int b;
};

int main()
{
  printf("sizeof(struct account) = %zu\n", sizeof(struct test));
  return 0;
}

 

struct test 의 맨 마지막 char c[]; 처럼 사용하면 된다.

test1 과 test2 는 에러가 나게된다. 

flexible array member not at end of struct 

라는 에러가 나게된다.

이는 flexible array member 는 구조체의 마지막 부분에 있지 않다는 것을 의미하고, 

사용하기 위해서는 구조체의 마지막 부분에 넣어야 한다는 것을 알게되었다.

맨 마지막에 넣은 것을 빌드해서 실행시켜보면, 

8이 나온다. int a 와 int b 만 포함이 된 것이다.

flexible array member 는 sizeof 에 포함이 되지 않는다. 

 

[가변길이 구조체 활용 방법]

C99 문서에 따르면

동적할당 시에 

struct s *p = malloc(sizeof(struct s) + sizeof(double[m])); 으로 선언하면 

{int n; double d[m]} 으로 사용할 수 있다고 나온다.

즉, struct s 에는 d[] 에 사이즈가 정의되어있지 않지만 동적 할당시에 기존 사이즈에다가 원하는 만큼 추가하여 할당을 해놓으면

가변으로 사용이 가능하다는 얘기이다. 

 

[테스트코드 작성]

c99 에 나와있는 동적할당을 토대로 사용해보자

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

struct test {
  int a;
  int b;
  char c[];
};

int main()
{
  printf("sizeof(struct account) = %zu\n", sizeof(struct test));

  struct test *t = (struct test*)malloc(sizeof(struct test) + 20*sizeof(char));

  t->a = 10;
  t->b = 20;
  strcpy(t->c, "hello world");

  printf("t->a = %s\n", t->c);
  
  free(t);
  return 0;
}

 

빌드 후 확인해보면 가변 멤버 구조체인 c 에 hello world 를 붙혀넣어서 사용이 가능한 것으로 보여진다.

이렇게 선언하면, char *c 를 선언한 뒤에 c 에 malloc 을 따로 해줄필요도 없게되고 메모리 주소도 연달아서 사용이 가능해진다.

반응형