구조체 메모리 크기 (Struct Memory Size): 두 판 사이의 차이

기술노트
(컴퓨터 과학 용어 정리 - 구조체 메모리 크기 (Struct Memory Size) 추가)
 
편집 요약 없음
태그: 되돌려진 기여
1번째 줄: 1번째 줄:
=== [C] 구조체 메모리 크기 (Struct Memory Size) ===
=== C 언어 구조체 메모리 크기 (Struct Memory Size) ===


typedef struct 선언 시, 변수 선언에 대한 메모리 공간 크기에 대해 알아보자
C 언어에서 `typedef struct`를 통해 정의된 구조체는 내부 멤버 변수들의 선언 순서와 자료형에 따라 메모리 공간의 크기 및 배치 방식이 달라집니다.


> 기업 필기 테스트에서 자주 나오는 유형이기도 함
> 기업 필기 테스트에서 자주 출제되는 주제입니다.


<br>
<br>


* char : 1바이트
==== 기본 타입별 크기 ====
* int : 4바이트
* double : 8바이트


`sizeof` 메소드를 통해 해당 변수의 사이즈를 알 있음
* `char` : 1바이트 
* `int` : 4바이트 
* `double` : 8바이트
 
`sizeof` 연산자를 통해 구조체 전체의 크기를 확인할 있습니다.


<br>
<br>


===== 크기 계산 =====
==== 예제 1: 기본 구조체 메모리 크기 ====


---
```c
 
<syntaxhighlight>c
typedef struct student {
typedef struct student {
     char a;
     char a;
     int b;
     int b;
}S;
} S;


void main() {
void main() {
     printf("메모리 크기 = %d/n", sizeof(S)); // 8
     printf("메모리 크기 = %d\n", sizeof(S)); // 출력: 8
}
}
</syntaxhighlight>
```


char는 1바이트고, int는 4바이트라서 5바이트가 필요하다.
* `char`는 1바이트, `int`는 4바이트이므로 단순 계산으로는 5바이트가 예상됩니다.
* 그러나 실제 출력값은 **8바이트**입니다.


하지만 메모리 공간은 5가 아닌 '''8이 찍힐 것이다'''.
'''''왜 그럴까요?''''


'''''Why?'''''
<br>
 
구조체가 메모리 공간을 잡는 원리에는 크게 두가지 규칙이 있다.


1. 각각의 멤버를 저장하기 위해서는 '''기본 4바이트 단위로 구성'''된다. (4의 배수 단위)
==== 구조체 정렬 규칙 ====
  즉, char 데이터 1개를 저장할 때 이 1개의 데이터를 읽어오기 위해서 1바이트를 읽어오는 것이 아니라 이 데이터가 포함된 '4바이트'를 읽는다.
2. 구조체 각 멤버 중에서 가장 큰 멤버의 크기에 영향을 받는다.


<br>
1. 각 멤버는 **자료형의 정렬 기준(alignment)**에 따라 메모리에 배치됩니다. 일반적으로 4바이트 단위로 정렬됩니다.
2. 구조체 전체의 크기는 **가장 큰 멤버의 크기 배수**가 되도록 패딩(padding)됩니다.


이 규칙이 적용된 메모리 공간은 아래와 같을 것이다.
예제에서 `char a` 뒤에는 3바이트의 패딩이 삽입되어, `int b`가 4바이트 정렬 주소에 위치하게 됩니다.


a는 char형이지만, 기본 4바이트 단위 구성으로 인해 3바이트의 여유공간이 생긴다.
[[파일:Struct-align1.png|center|500px]]
 
<img src="http://postfiles2.naver.net/20150930_177/sharonichoya_1443599417738eaCq5_PNG/%B1%B8%C1%B6%C3%BC%C5%A9%B1%E23.png?type=w2">


<br>
<br>


그렇다면 이와 같을 때는 어떨까?
==== 예제 2: 연속된 char 변수 ====


<syntaxhighlight>c
```c
typedef struct student {
typedef struct student {
     char a;
     char a;
     char b;
     char b;
     int c;
     int c;
}S;
} S;
</syntaxhighlight>
```


<img src="http://postfiles15.naver.net/20150930_14/sharonichoya_1443599661246BGweK_PNG/%B1%D7%B8%B21.png?type=w2">
* `char a`와 `char b`는 하나의 4바이트 블록에 함께 배치됩니다.
* 이후 2바이트의 패딩이 추가되고, `int c`가 그 다음 블록에 위치합니다.


똑같이 8바이트가 필요하며, char형으로 선언된 a,b가 4바이트 안에 함께 들어가고 2바이트의 여유 공간이 생긴다.
[[파일:Struct-align2.png|center|500px]]
 
→ 총 8바이트


<br>
<br>


이제부터 헷갈리는 경우다.
==== 예제 3: 멤버 순서 변경 ====


<syntaxhighlight>c
```c
typedef struct student {
typedef struct student {
     char a;
     char a;
     int c;
     int c;
     char b;
     char b;
}S;
} S;
</syntaxhighlight>
```


구성은 같지만, 순서가 다르다.
* `char a` 이후 3바이트 패딩 → `int c` 정렬 
* `char b`는 다시 4바이트 정렬을 위해 별도 블록에 위치 + 3바이트 패딩


자료타입은 일치하지만, 선언된 순서에 따라 할당되는 메모리 공간이 아래와 같이 달라진다.
[[파일:Struct-align3.png|center|500px]]


<img src="http://postfiles15.naver.net/20150930_142/sharonichoya_1443599763574jksKW_PNG/%B1%D7%B8%B22.png?type=w2">
→ 총 12바이트


이 경우에는 총 12바이트가 필요하게 된다.
<br>


<br>
==== 예제 4: double 포함 구조체 ====


<syntaxhighlight>c
```c
typedef struct student {
typedef struct student {
     char a;
     char a;
     int c;
     int c;
     double b;
     double b;
}S;
} S;
</syntaxhighlight>
```


두 규칙이 모두 적용되는 상황이다. b가 double로 8바이트이므로 기본 공간이 8바이트로 설정된다. 하지만 a와 c는 8바이트로 해결이 가능하기 때문에 16바이트로 해결이 가능하다.
* `double`이 가장 큰 멤버이므로 전체 구조체는 **8바이트 정렬**을 따릅니다.
* `char` + 패딩 + `int`는 8바이트로 정렬 가능하며, `double`이 그 다음에 배치되어 총 16바이트가 됩니다.


<img src="http://postfiles4.naver.net/20150930_83/sharonichoya_1443600192056XIAc4_PNG/%B1%D7%B8%B24.png?type=w2">
[[파일:Struct-align4.png|center|500px]]


<br>
<br>
==== 정리 ====
* 구조체의 메모리 크기는 멤버의 **자료형 크기와 정렬 기준**에 따라 달라집니다.
* 멤버의 **선언 순서**에 따라 불필요한 패딩이 생길 수 있으며, 이를 줄이기 위해 **작은 타입을 먼저 선언**하는 것이 유리합니다.


<br>
<br>


##### [참고자료]
==== 참고자료 ====


[링크](<http://blog.naver.com/PostView.nhn?blogId=sharonichoya&logNo=220495444611>)
* [원문 블로그 보기](http://blog.naver.com/PostView.nhn?blogId=sharonichoya&logNo=220495444611)

2025년 4월 21일 (월) 14:12 판

C 언어 구조체 메모리 크기 (Struct Memory Size)

C 언어에서 `typedef struct`를 통해 정의된 구조체는 내부 멤버 변수들의 선언 순서와 자료형에 따라 메모리 공간의 크기 및 배치 방식이 달라집니다.

> 기업 필기 테스트에서 자주 출제되는 주제입니다.


기본 타입별 크기

  • `char` : 1바이트
  • `int` : 4바이트
  • `double` : 8바이트

`sizeof` 연산자를 통해 구조체 전체의 크기를 확인할 수 있습니다.


예제 1: 기본 구조체 메모리 크기

```c typedef struct student {

   char a;
   int b;

} S;

void main() {

   printf("메모리 크기 = %d\n", sizeof(S)); // 출력: 8

} ```

  • `char`는 1바이트, `int`는 4바이트이므로 단순 계산으로는 5바이트가 예상됩니다.
  • 그러나 실제 출력값은 **8바이트**입니다.

왜 그럴까요?'


구조체 정렬 규칙

1. 각 멤버는 **자료형의 정렬 기준(alignment)**에 따라 메모리에 배치됩니다. 일반적으로 4바이트 단위로 정렬됩니다. 2. 구조체 전체의 크기는 **가장 큰 멤버의 크기 배수**가 되도록 패딩(padding)됩니다.

예제에서 `char a` 뒤에는 3바이트의 패딩이 삽입되어, `int b`가 4바이트 정렬 주소에 위치하게 됩니다.


예제 2: 연속된 char 변수

```c typedef struct student {

   char a;
   char b;
   int c;

} S; ```

  • `char a`와 `char b`는 하나의 4바이트 블록에 함께 배치됩니다.
  • 이후 2바이트의 패딩이 추가되고, `int c`가 그 다음 블록에 위치합니다.

→ 총 8바이트


예제 3: 멤버 순서 변경

```c typedef struct student {

   char a;
   int c;
   char b;

} S; ```

  • `char a` 이후 3바이트 패딩 → `int c` 정렬
  • `char b`는 다시 4바이트 정렬을 위해 별도 블록에 위치 + 3바이트 패딩

→ 총 12바이트


예제 4: double 포함 구조체

```c typedef struct student {

   char a;
   int c;
   double b;

} S; ```

  • `double`이 가장 큰 멤버이므로 전체 구조체는 **8바이트 정렬**을 따릅니다.
  • `char` + 패딩 + `int`는 8바이트로 정렬 가능하며, `double`이 그 다음에 배치되어 총 16바이트가 됩니다.


정리

  • 구조체의 메모리 크기는 멤버의 **자료형 크기와 정렬 기준**에 따라 달라집니다.
  • 멤버의 **선언 순서**에 따라 불필요한 패딩이 생길 수 있으며, 이를 줄이기 위해 **작은 타입을 먼저 선언**하는 것이 유리합니다.


참고자료