C에서 구조체 정렬 및 패딩 사용
이 기사에서는 C에서struct
정렬 및 패딩을 사용하는 방법에 대한 몇 가지 방법을 설명합니다.
C에서 정렬 및 패딩의 기본 사항 이해
메모리의 모든 개체는char
, short
, int
, long
, pointer
등과 같은 기본 데이터 유형으로 표시됩니다. 이러한 데이터 유형은 메모리에서 해당 크기를 갖습니다. 대부분의 최신 64 비트 데스크탑 프로세서에서 크기는char
의 경우 1 바이트,short
의 경우 2 바이트,int
의 경우 4 바이트,포인터
의 경우 8 바이트 등입니다. 이는 보장 된 크기 (char
제외)는 아니지만sizeof
연산자를 사용하여 개체의 크기를 검색 할 수 있습니다. 이제 정렬은 컴파일러가 변수를 메모리에 배치하는 데 사용하는 방법이며, 이는 각 기본 데이터 유형이 해당 크기로 나눌 수있는 주소에 저장됨을 의미합니다.
일반적으로 정렬은 데이터 개체에 더 빠르고 효율적으로 액세스하는 데 사용됩니다. 정렬은 지속적으로 선언 된 서로 다른 데이터 유형이 주소 사이에 약간의 간격을 포함하도록합니다. 즉, 다음 예제와 같이 하나의 포인터와char
로 구조st1
을 선언하면 총 16 바이트를 차지합니다. 그러나 단일 포인터는 8 바이트를 사용하고char
는 1 바이트를 사용하므로st1
구조체가 9 바이트를 차지해야한다고 생각할 것입니다. 그러나 모든 멤버가 가장 큰 멤버의 크기 (예: 8 바이트)에 맞춰진 것처럼 작동합니다. st2
구조체는 7 개의char
멤버 배열이 있다는 점을 제외하고는 동일한 양의 메모리를 차지하는 유사한 구조체를 보여줍니다.
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char const *argv[]) {
typedef struct {
char *p;
char c2;
} st1;
typedef struct {
char *p;
char c2;
char padding[7];
} st2;
printf("sizeof st1 = %zu\n", sizeof(st1));
printf("sizeof st2 = %zu\n", sizeof(st2));
exit(EXIT_SUCCESS);
}
출력:
sizeof st1 = 16
sizeof st2 = 16
멤버 재정렬 기법을 사용하여 C에서 개체의 공간 절약
이전 예제는 구조가 다른 유형을 포함하고 정렬 경계를 채우지 않을 때 약간의 메모리 낭비가 있음을 보여줍니다. 그러나 구조 멤버를 다시 정렬하고 추가 공간을 절약 할 수있는 경우가 있습니다.
다음 예제 코드는 중간에 가장 큰 멤버(char *
)가있는foo1
구조체와 첫 번째 멤버와 동일한 멤버가있는foo2
를 정의합니다. 이 두 개체의 크기는 24 바이트와 16 바이트로 다릅니다. 이것은 데이터 멤버의 순서와 관련이 있습니다. foo1
구조에서p
는 8로 나눌 수있는 주소에 정렬되어야합니다. 따라서int
및short
가 총 8 바이트를 차지하고 두 개의char *
가 차지합니다. 8 바이트도 마찬가지입니다. 그러나p
를 1 위로 이동하면 다음 멤버가 8 바이트로 압축되어 정렬 규칙도 충족됩니다. 따라서foo2
의 크기는 총 16 바이트이며struct
로 압축되도록 호출됩니다. gcc
컴파일러에는 정렬되지 않은struct
멤버도 강제로 패킹 할 수있는 특수__attribute__ ((packed))
지정자가 있습니다.
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char const *argv[]) {
typedef struct {
int n1;
short s1;
char *p;
char c1;
char c2;
} foo1;
typedef struct {
char *p;
int n1;
short s1;
char c1;
char c2;
} foo2;
typedef struct {
int n1;
short s1;
char *p;
char c1;
char c2;
} __attribute__((packed)) foo3;
printf("sizeof foo1 = %zu\n", sizeof(foo1));
printf("sizeof foo2 = %zu\n", sizeof(foo2));
printf("sizeof foo3 = %zu\n", sizeof(foo3));
exit(EXIT_SUCCESS);
}
출력:
sizeof foo1 = 24
sizeof foo2 = 16
sizeof foo3 = 16
Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.
LinkedIn Facebook