프로그래밍/C,C++,C#

[C,C++,C#] 구조체 메모리 크기 계산

Beginner:) 2023. 6. 4.
320x100

C언어를 하면 구조체를 초반부에 배우는데, 좀 더 깊게 들어가 본다.

 

아래 코드의 결과는?

#include <stdio.h>

struct Temp{
    double a;
    int b;
    char c;
};

int main()
{
    struct Temp temp;

    printf("struct size = %ld\n", sizeof(temp));
    return 0;
}

결과는 16이다.

 

8(double) + 1(char) + 4(int) = 13으로 계산하였다면 잘못 알고 있는 것이다.

 

8로 기준을 잡고 순서대로 생성과정을 설명하자면,

 

1. double이 들어왔으니 8byte를 생성+8byte 할당 (구조체 총 크기: 8, 남은 공간: 0/8)

2. int가 들어왔으니 8byte를 생성+4byte 할당 (구조체 총 크기: 16, 남은 공간: 12/16)

3. char가 들어왔으니 1byte 할당 (구조체 총 크기: 16, 남은 공간: 13/16)


계산하는 방법은 구조체 멤버 변수 중 가장 큰 타입을 기준으로 공간을 잡지만, 그 안에서는 4byte 기준으로 잡으며 순서도 중요하다는 것만 기억하면 된다. (또는 간단히 작은 멤버변수부터 선언하면 편리하다)

 

기억하기엔 말이 좀 어려운데 예제를 보자.

 

 

1. 가장 큰 타입을 기준으로 한다.

double이 가장 큰 타입이므로 char를 할당할 때 8byte가 잡힌다.

#include <stdio.h>

struct Temp{
    double a;
    char b;
};

int main()
{
    struct Temp temp;

    printf("struct size = %ld\n", sizeof(temp));
    return 0;
}

 

2. 그 안에서는 4byte 기준으로 잡는다.   (***** 다른 글을 읽어봤지만 이에 대한 내용은 없어서 추론하였으므로 맹신 X)

char 타입 6개, short 타입 1개로 총 8byte이기 때문에 double 기준으로 공간을 잡으면 16byte가 정상이지만 24byte를 출력한다.

4byte를 기준으로 잡기 때문에 char 3개에서 3byte를 차지하였고, short는 4byte 기준에 들어갈 공간이 없기 때문에 다음 4byte에 할당이 된다. 이후 남은 2byte를 char 2개가 할당하고 하나 남은 char는 새로운 8byte에 할당된다.

출력 로그를 보면 short e의 주소값이 char d의 +1이 아닌 +2이다.

#include <stdio.h>

struct Temp{
    double a;
    char b;
    char c;
    char d;
    short e;
    char f;
    char g;
    char h;
};

int main()
{
    struct Temp temp;

    printf("struct size = %ld\n", sizeof(temp));
    printf("address a: %p\n",&temp.a);
    printf("address b: %p\n",&temp.b);
    printf("address c: %p\n",&temp.c);
    printf("address d: %p\n",&temp.d);
    printf("address e: %p\n",&temp.e);
    printf("address f: %p\n",&temp.f);
    printf("address g: %p\n",&temp.g);
    printf("address h: %p\n",&temp.h);

    return 0;
}

 

 

3. 순서도 중요하다. (align 규칙)

int가 들어옴으로써 8byte를 생성하고, double이 들어와 8byte 공간을 생성하여 총 16byte며 남은 공간이 4byte가 있으니 char가 들어갈 공간이 있어 보이지만, 새로운 8byte 공간을 생성한다.

#include <stdio.h>

struct Temp{
    int a;
    double b;
    char c;
};

int main()
{
    struct Temp temp;

    printf("struct size = %ld\n", sizeof(temp));
    return 0;
}

 

아래는 C++ stuct type 간 상호 offset의 align 매뉴얼이다. 

 

 


 

그래서 메모리를 절약하려면 구조체 멤버변수의 순서도 중요하다.

 

또 다른 해결방법은 아래 링크에...

2023.06.04 - [프로그래밍/C,C++,C#] - [C,C++,C#] 구조체 padding 제거(feat. 구조체 크기 계산)

 

[C,C++,C#] 구조체 padding 제거(feat. 구조체 크기 계산)

이전 글에서 구조체의 크기가 멤버 변수보다 크게 잡히는 현상을 확인했다. 2023.06.04 - [프로그래밍/C,C++,C#] - [C,C++,C#] 구조체 메모리 크기 계산 [C,C++,C#] 구조체 메모리 크기 계산 C언어를 하면 구

park-duck.tistory.com

 

반응형

댓글