C언어의 데이터 타입은 char, short, int, long, long long, float, double이 있습니다. 이 들이 메모리에서 차지하는 크기는 sizeof연산자를 이용하여 그 크기를 알 수 있습니다.
64bit OS 환경을 기준으로 예를들면, sizeof(char)는 1, sizeof(short)는 2, sizeof(int)는 4, sizeof(long)는 8, ... 입니다.
임의로 여러 개의 변수들을 선언하고 변수가 위치한 메모리 번지를 출력하는 간단한 프로그램을 작성하여 그 내용을 알아보겠습니다.
#include <stdio.h>
int main()
{
char ch1;
char ch2;
int i1;
long l1;
char ch3;
int i2;
long l2;
printf("&ch1 = %p\n", &ch1);
printf("&ch2 = %p\n", &ch2);
printf("&i1 = %p\n", &i1);
printf("&l1 = %p\n", &l1);
return 0;
}
결과>
&ch1 = 0x7ffd128e3ec5
&ch2 = 0x7ffd128e3ec6
&i1 = 0x7ffd128e3ec8
&l1 = 0x7ffd128e3ed0
위의 변수들의 위치를 출력해보면 ch1이 1바이트이므로 ch2의 위치는 바로 그 다음에 위치하는 것을 알 수 있습니다. 그런데, i1은 ch2의 크기가 1이므로 바로 다음 번지에 위치해야 되는 데, 그렇지 않은 것을 확인할 수 있습니다. 그리고 l1변수도 i1의 크기 4바이트 뒤에 위치하지 않는 것을 확인할 수 있습니다. 프로그램을 실행할 때마다 메모리 번지가 바뀌기 때문에 조금씩 차이는 있겠지만, 변수의 위치에는 특징이 있습니다.
바로 그 특징은 변수의 위치는 sizeof(타입)의 배수에 해당하는 메모리 번지에 위치한다는 것입니다.
예를들면, char 타입의 변수 1바이트이므로 1의 배수 즉, 아무 곳이나 위치할 수 있고, short는 2의 배수, int는 4의 배수 ... 등의 규칙을 갖는다는 것입니다. 대부분의 CPU은 이처럼 성능을 위하여 변수의 위치는 그 타입의 크기 배수에 위치하게 됩니다. (물론 컴파일을 option으로 이어서 위치하게 할 수는 있으나 특별한 옵션을 주지 않으면 배수의 규칙을 따릅니다.)
구조체의 멤버 변수도 마찬가지로 타입 크기의 배수 규칙을 따르게 됩니다. 뿐만 아니라 구조체의 크기는 멤버변수 중에서 가장 큰 타입의 배수의 규칙도 따릅니다.
struct type1
{
char ch1;
char ch2;
long l1;
};
struct type2
{
char ch1;
long l1;
char ch2;
};
위의 구조체 type1과 type2는 모두 64bit 기준으로 멤버변수의 총 크기는 1 + 1 + 8 = 10바이트를 차지 하는 것 처럼 보입니다.
int main()
{
printf("sizeof type1 = %d\n", sizeof(struct type1));
printf("sizeof type2 = %d\n", sizeof(struct type2));
return 0;
}
결과>
sizeof type1 = 16
sizeof type2 = 24
그러나, 위와 같이 실제로 크기를 출력해보면 크기가 차이남을 알 수 있습니다.
struct type1은 char 2개가 연속으로 위치하고 이후에 long변수(8의 배수에 있어야 하기 때문)가 있기 때문에
ch1(1바이트) + ch2(1바이트) + 공간(6바이트) + long (8바이트) = 16 바이트
가 됩니다.
struct type2은 char 1개 + long변수 (8의 배수 위치) + char 1개인데, 전체 길이는 long이 가장 크므로 8의 배수여야 합니다.
char(1바이트) + 공간(7바이트) + long(8바이트) + char(1바이트) + 공간(7바이트) = 24바이트
가 됩니다. 구조체의 크기가 멤버 변수중에서 가장 큰 데이터의 배수로 적용되는 이유는 배열의 경우 연속으로 이어져야 하는 데, arr[1]에 있는 변수들의 위가 각 타입의 배수에 위치하지 않게되는 것을 방지하기 위함입니다.
이 단원에서 크게 중요하지 않을 수도 있는, 변수의 위치와 구조체의 멤버변수의 위치, 구조체의 크기를 다룬 이유는 이 구조를 모르면 문제가 발생하는 경우들이 가끔 발생하곤 합니다. 특히, 시스템 프로그래밍이나, Framework와 같은 개발 tool을 개발하는 경우 등에서는 큰 영향을 줄 수 있습니다.
'C언어 > 문법' 카테고리의 다른 글
31. 열거형(enum) - 정수형 상수 그룹 (0) | 2019.12.07 |
---|---|
30. 공용체(union) - 멤버간의 메모리 공유 (0) | 2019.12.07 |
28. 구조체(struct) - 구조체 내의 구조체 (0) | 2019.12.05 |
27. 구조체(struct) - 비트 필드(bit field) (2) | 2019.12.05 |
26. 구조체(struct) - 기초 (0) | 2019.12.04 |