핵심 정리
구조체 멤버 정렬
C 언어는 CPU에서 메모리에 접근하는 효율을 높이기 위해 구조체를 일정한 크기로 정렬을 합니다. 이때 멤버 중에서 큰 자료형 크기의 배수로 정렬하며 남는 공간을 채우는 것을 패딩이라 부릅니다.
// 1 + 4 = 5 바이트 크기의 구조체 struct PacketHeader { char flags; // 1바이트 int offset; // 4바이트 }; printf("%d\n", sizeof(struct PacketHeader)); // 8: 가장 큰 자료형은 int. int의 크기 4바이트로 정렬 // 남는 3바이트는 패딩
구조체의 정렬 크기를 조절하려면 컴파일러에서 제공하는 지시자를 사용해야 합니다.
Visual Studio, GCC 4.0 이상
#pragma pack(push, 정렬크기) #pragma pack(pop)
GCC 4.0 미만
__attribute__((aligned(정렬크기),packed))
구조체의 내용을 0으로 설정하기
구조체의 내용을 모두 0으로 설정하려면 memset 함수를 사용합니다.
memset(구조체포인터, 0, sizeof(struct 구조체));
구조체의 내용을 복사하기
구조체의 내용을 복사하려면 memcpy 함수를 사용합니다.
memcpy(목적지포인터, 원본포인터, sizeof(struct 구조체));
구조체 배열
구조체 변수를 선언하려면 [ ] (대괄호)에 크기를 지정합니다. 구조체 배열의 멤버에 접근하려면 [ ]에 인덱스를 지정한 뒤 .으로 접근합니다.
// 구조체 배열 선언하기 struct 구조체이름 변수이름[크기]; // 구조체 배열을 선언하는 동시에 값을 초기화 struct 구조체이름 변수이름[크기] = { { .멤버이름1 = 값1, .멤버이름2 = 값2 }, { .멤버이름1 = 값3, .멤버이름2 = 값4 } }; struct 구조체이름 변수이름[크기] = { { 값1, 값2 }, { 값3, 값4 } }; 배열[인덱스].멤버; // 구조체 배열에서 요소의 멤버 값을 가져옴 배열[인덱스].멤버 = 값; // 구조체 배열에서 요소의 멤버에 값을 저장
구조체 포인터 배열
구조체 포인터 배열을 선언하려면 포인터 변수 이름 뒤에 [ ]를 붙인 뒤 크기를 지정합니다. 이때 배열의 요소에는 메모리를 할당해야 하며 멤버에 접근할 때는 [ ]에 인덱스를 지정한 뒤 ->로 접근합니다.
// 구조체 포인터 배열 선언하기 struct 구조체이름 *포인터이름[크기]; // 구조체 포인터 배열에 메모리 할당하기 for (int i = 0; i < 크기; i++) // 배열 크기만큼 반복 { 배열[i] = malloc(sizeof(struct 구조체)); // 각 요소에 구조체 크기만큼 메모리 할당 } 배열[인덱스]->멤버; // 구조체 포인터 배열에서 요소의 멤버 값을 가져옴 배열[인덱스]->멤버 = 값; // 구조체 포인터 배열에서 요소의 멤버에 값을 저장 // 구조체 포인터 배열의 메모리 해제하기 for (int i = 0; i < 크기; i++) // 배열 크기만큼 반복 { free(포인터[i]); // 각 요소의 동적 메모리 해제 }