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 Programming Language 문법

1. C 프로그래밍 언어는? 2. C언어 개발 환경 (실습 환경) 3. C언어의 컴파일 과정 4. C 소스 파일 구성 5. 주석문(Comment) 6. 식별자 명명 규칙 7. C 프로그래밍의 시작 - 함수 8. 변수와 상수 (정수형) 9. 변..

www.it-note.kr

 

블로그 이미지

사용자 자연&사람

행복한 개발자 programmer since 1995.

Tag ,

댓글을 달아 주세요