반응형
아래와 같은 구조체 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가 되어서 아래와 같은 결과가 나오게 된다.
반응형
'개발 > C, C++' 카테고리의 다른 글
C++ - 함수 템플릿 (Function Template) (0) | 2021.07.22 |
---|---|
허상 포인터 (Dangling Pointer) (0) | 2021.07.18 |
C++ - 컨테이너와 반복자 (Container and Iterator) (0) | 2021.06.11 |
C++ - 인라인(inline) 함수 (0) | 2021.05.19 |
단락 평가 Short Circuit (0) | 2021.05.11 |
댓글