C에서 구조체 정렬 및 패딩 사용

Jinku Hu 2023년10월12일
  1. C에서 정렬 및 패딩의 기본 사항 이해
  2. 멤버 재정렬 기법을 사용하여 C에서 개체의 공간 절약
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로 나눌 수있는 주소에 정렬되어야합니다. 따라서intshort가 총 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
작가: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

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

관련 문장 - C Struct