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

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


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


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


<br>
<br>


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


* `char` : 1바이트 
`sizeof` 메소드를 통해 해당 변수의 사이즈를 알 수 있음
* `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;


int main() {
void main() {
     printf("메모리 크기 = %d\n", sizeof(S)); // 출력: 8
     printf("메모리 크기 = %d/n", sizeof(S)); // 8
    return 0;
}
}
```
</syntaxhighlight>
 
char는 1바이트고, int는 4바이트라서 5바이트가 필요하다.
 
하지만 메모리 공간은 5가 아닌 '''8이 찍힐 것이다'''.


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


'''''왜 그럴까요?'''''
구조체가 메모리 공간을 잡는 원리에는 크게 두가지 규칙이 있다.
 
1. 각각의 멤버를 저장하기 위해서는 '''기본 4바이트 단위로 구성'''된다. (4의 배수 단위)
  즉, char 데이터 1개를 저장할 때 이 1개의 데이터를 읽어오기 위해서 1바이트를 읽어오는 것이 아니라 이 데이터가 포함된 '4바이트'를 읽는다.
2. 구조체 각 멤버 중에서 가장 큰 멤버의 크기에 영향을 받는다.


<br>
<br>


==== 구조체 정렬 규칙 ====
이 규칙이 적용된 메모리 공간은 아래와 같을 것이다.


1. 각 멤버는 **자료형의 정렬 기준(alignment)**에 따라 메모리에 배치됩니다. 일반적으로 4바이트 단위로 정렬됩니다. 
a는 char형이지만, 기본 4바이트 단위 구성으로 인해 3바이트의 여유공간이 생긴다.
2. 구조체 전체의 크기는 **가장 큰 멤버의 크기 배수**가 되도록 패딩(padding)됩니다.


예제에서 `char a` 뒤에는 3바이트의 패딩이 삽입되어, `int b`가 4바이트 정렬 주소에 위치하게 됩니다.
<img src="http://postfiles2.naver.net/20150930_177/sharonichoya_1443599417738eaCq5_PNG/%B1%B8%C1%B6%C3%BC%C5%A9%B1%E23.png?type=w2">
 
[[파일:Struct-align1.png|center|600px]]


<br>
<br>


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


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


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


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


<br>
<br>


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


```c
<syntaxhighlight>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|600px]]
자료타입은 일치하지만, 선언된 순서에 따라 할당되는 메모리 공간이 아래와 같이 달라진다.


12바이트
<img src="http://postfiles15.naver.net/20150930_142/sharonichoya_1443599763574jksKW_PNG/%B1%D7%B8%B22.png?type=w2">
 
이 경우에는 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>


* `double`의 정렬 기준은 8바이트입니다.
두 규칙이 모두 적용되는 상황이다. b가 double로 8바이트이므로 기본 공간이 8바이트로 설정된다. 하지만 a와 c는 8바이트로 해결이 가능하기 때문에 16바이트로 해결이 가능하다.
* 전체 구조체는 8바이트 단위 정렬을 따르며, 멤버들이 이에 맞게 배치되어 총 16바이트가 됩니다.


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


<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:50 판

[C] 구조체 메모리 크기 (Struct Memory Size)

typedef struct 선언 시, 변수 선언에 대한 메모리 공간 크기에 대해 알아보자

> 기업 필기 테스트에서 자주 나오는 유형이기도 함


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

`sizeof` 메소드를 통해 해당 변수의 사이즈를 알 수 있음


크기 계산

---

c
typedef struct student {
    char a;
    int b;
}S;

void main() {
    printf("메모리 크기 = %d/n", sizeof(S)); // 8
}

char는 1바이트고, int는 4바이트라서 5바이트가 필요하다.

하지만 메모리 공간은 5가 아닌 8이 찍힐 것이다.

Why?

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

1. 각각의 멤버를 저장하기 위해서는 기본 4바이트 단위로 구성된다. (4의 배수 단위)

  즉, char 데이터 1개를 저장할 때 이 1개의 데이터를 읽어오기 위해서 1바이트를 읽어오는 것이 아니라 이 데이터가 포함된 '4바이트'를 읽는다.

2. 구조체 각 멤버 중에서 가장 큰 멤버의 크기에 영향을 받는다.


이 규칙이 적용된 메모리 공간은 아래와 같을 것이다.

a는 char형이지만, 기본 4바이트 단위 구성으로 인해 3바이트의 여유공간이 생긴다.

<img src="http://postfiles2.naver.net/20150930_177/sharonichoya_1443599417738eaCq5_PNG/%B1%B8%C1%B6%C3%BC%C5%A9%B1%E23.png?type=w2">


그렇다면 이와 같을 때는 어떨까?

c
typedef struct student {
    char a;
    char b;
    int c;
}S;

<img src="http://postfiles15.naver.net/20150930_14/sharonichoya_1443599661246BGweK_PNG/%B1%D7%B8%B21.png?type=w2">

똑같이 8바이트가 필요하며, char형으로 선언된 a,b가 4바이트 안에 함께 들어가고 2바이트의 여유 공간이 생긴다.


이제부터 헷갈리는 경우다.

c
typedef struct student {
    char a;
    int c;
    char b;
}S;

구성은 같지만, 순서가 다르다.

자료타입은 일치하지만, 선언된 순서에 따라 할당되는 메모리 공간이 아래와 같이 달라진다.

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

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


c
typedef struct student {
    char a;
    int c;
    double b;
}S;

두 규칙이 모두 적용되는 상황이다. b가 double로 8바이트이므로 기본 공간이 8바이트로 설정된다. 하지만 a와 c는 8바이트로 해결이 가능하기 때문에 16바이트로 해결이 가능하다.

<img src="http://postfiles4.naver.net/20150930_83/sharonichoya_1443600192056XIAc4_PNG/%B1%D7%B8%B24.png?type=w2">



          1. [참고자료]

[링크](<http://blog.naver.com/PostView.nhn?blogId=sharonichoya&logNo=220495444611>)