본문 바로가기
개발/C, C++

구조체의 크기

by 피로물든딸기 2021. 6. 19.
반응형

C, C++ 전체 링크

 

아래와 같은 구조체 st1이 있다.

#include <stdio.h>

typedef struct st1
{
	char a;
	short b;
	int c;
	char d;
	long long e;
	char* f;
	int* g;
};

int main(void)
{
	printf("char a      size : %d\n", sizeof(char));
	printf("short b     size : %d\n", sizeof(short));
	printf("int c       size : %d\n", sizeof(int));
	printf("char d      size : %d\n", sizeof(char));
	printf("long long e size : %d\n", sizeof(long long));
	printf("char* f     size : %d\n", sizeof(char*));
	printf("int* g      size : %d\n", sizeof(int*));

	printf("\n----------------------------------\n");

	printf("struct 1 size : %d\n", sizeof(st1));

	return 0;
}

 

각 멤버를 더하면 1 + 2 + 4 + 1 + 8 + 4 + 4 = 24지만 구조체의 크기는 32가 나온다.

 

C언어에서 구조체를 정렬할 때 멤버 중 가장 큰 자료형 크기의 배수로 정렬하기 때문이다.

 

1 + padding + 2 + 4 → 8

1 + padding → 8

8 → 8

4 + 4 → 8

ㄴ 총 32가 된다.

 

stddef.h를 선언하여 offsetof로 멤버의 상대 위치를 확인할 수 있다.

#include <stdio.h>
#include <stddef.h>

typedef struct st1
{
	char a;
	short b;
	int c;
	char d;
	long long e;
	char* f;
	int* g;
};

int main(void)
{
	printf("char a      size : %d\n", sizeof(char));
	printf("short b     size : %d\n", sizeof(short));
	printf("int c       size : %d\n", sizeof(int));
	printf("char d      size : %d\n", sizeof(char));
	printf("long long e size : %d\n", sizeof(long long));
	printf("char* f     size : %d\n", sizeof(char*));
	printf("int* g      size : %d\n", sizeof(int*));

	printf("\n----------------------------------\n");

	printf("struct 1 size : %d\n", sizeof(st1));
	printf("a : %d\n", offsetof(struct st1, a));
	printf("b : %d\n", offsetof(struct st1, b));
	printf("c : %d\n", offsetof(struct st1, c));
	printf("d : %d\n", offsetof(struct st1, d));
	printf("e : %d\n", offsetof(struct st1, e));
	printf("f : %d\n", offsetof(struct st1, f));
	printf("g : %d\n", offsetof(struct st1, g));

	return 0;
}


#pragma pack으로 구조체 정렬 크기를 조절할 수 있다.

#include <stdio.h>
#include <stddef.h>

#pragma pack(push, 1)
typedef struct st1
{
	char a;
	short b;
	int c;
	char d;
	long long e;
	char* f;
	int* g;
};
#pragma pack(pop)

#pragma pack(push, 2)
typedef struct st2
{
	char a;
	short b;
	int c;
	char d;
	long long e;
	char* f;
	int* g;
};
#pragma pack(pop)

#pragma pack(push, 4)
typedef struct st3
{
	char a;
	short b;
	int c;
	char d;
	long long e;
	char* f;
	int* g;
};
#pragma pack(pop)

#pragma pack(push, 8)
typedef struct st4
{
	char a;
	short b;
	int c;
	char d;
	long long e;
	char* f;
	int* g;
};
#pragma pack(pop) 

int main(void)
{
	printf("char a      size : %d\n", sizeof(char));
	printf("short b     size : %d\n", sizeof(short));
	printf("int c       size : %d\n", sizeof(int));
	printf("char d      size : %d\n", sizeof(char));
	printf("long long e size : %d\n", sizeof(long long));
	printf("char* f     size : %d\n", sizeof(char*));
	printf("int* g      size : %d\n", sizeof(int*));

	printf("\n----------------------------------\n");

	printf("struct 1 size : %d\n", sizeof(st1));
	printf("struct 2 size : %d\n", sizeof(st2));
	printf("struct 3 size : %d\n", sizeof(st3));
	printf("struct 4 size : %d\n", sizeof(st4));

	return 0;
}

 

pack(push, 1) → 정렬 크기를 1로 설정한 경우 구조체 멤버의 총 합이 구조체 크기와 같은 것을 알 수 있다.

pack(pop)은 정렬 설정을 이전 상태로 되돌리는 역할을 한다.

 

마지막으로 x64로 설정하고 결과를 실행해보자.

 

64비트에서는 포인터의 크기가 8byte가 되어서 아래와 같은 결과가 나오게 된다.

반응형

댓글