인프런 커뮤니티 질문&답변

cjkoo96님의 프로필 이미지
cjkoo96

작성한 질문수

홍정모의 따라하며 배우는 C언어

14.3 구조체의 메모리 할당

메모리 패딩관련 질문입니다.

해결된 질문

작성

·

634

0

1 word 당 bytes가 적으면 여러번 데이터를 주고 받아야하므로 더 느리게 된다. 그러나 메모리 공간은 적게 잡아먹는다.

-> 느리지만, 메모리공간효율 좋음

1 word 당 bytes가 많으면 속도는 빠르게 되지만, 메모리 공간을 많이 잡아먹는다.

->빠르지만, 메모리공간효율 나쁨

라고 이해했습니다. 제가 잘 이해한 건가요?? 어떤게 더 효율적인 건가요??

그리고 11:52초쯤 교수님께서 실행한 코드 

struct Padded2

{

float a;

double b;

char c;

};

struct Padded2 p2;

printf("\nstruct Padded2 p2\n");

printf("Sizeof %zd %zd\n", sizeof(struct Padded2), sizeof(p2));

printf("%lld\n", (long long)&p2);

printf("%lld\n", (long long)&p2.a);

printf("%lld\n", (long long)&p2.b);

printf("%lld\n", (long long)&p2.c);

}

이 코드가 x86에서도 size가 24로 나옵니다.

교수님께서 설명하신 점과는 달리 x86도 1 word가 8bytes인 거겠죠??

답변 5

2

- 1 워드의 크기가 클 수록 더 많이 묶어서 보내는 것이기 때문에 CPU가 메모리를 왔다 갔다 하는 과정이 줄어드므로 빠른 것이 맞습니다.

- 그러나 메모리 공간 효율성은 워드 크기에 따라 달라지는 것이라기보단, 각각의 다른 자료형을 가진 구조체 변수들이 어떤 순서로 선언되느냐에 따라 패딩이 들어가는 양이 결정되기 때문에 공간 효율성은 이와 관련이 있습니다. 똑같은 구조체라도 구조체 내의 변수 선언 순서에 따라 구조체 크기가 달라질 수 있기 때문입니다. 

- 질문자님께서는 x86 같은 1word = 4byte = 32bit 체계에서는  4byte 단위로 주고 받기 때문에 size가 24가 아닌 다른 답이 나와야 한다고 생각하신 것 같은데 맞으신가요? 😮 저도 질문자님의 질문을 보고 x86, x64에서 다 돌려봤는데 다 똑같은 결과로 나왔습니다. 그래서 찾아 봤는데 https://stackoverflow.com/questions/55920103/why-is-the-alignment-the-same-on-32-bit-and-64-bit-systems

위 링크에 따르면 구조체 내에서 결정되는 패딩의 크기는 워드 사이즈보단  구조체를 구성하는 변수들의 데이터 타입 에 의해 결정이 된다고 합니다. char, int, float, double은 32bit 체계든, 64bit 체계든 데이터 크기가 같기 때문에 어떤 체계에서든간에 char, int, float, double 변수들만을 가지는 구조체 크기는  같습니다 

https://sleep365.tistory.com/81

위 블로그 글에서도 도움을 받으실 수 있을겁니다. 32bit 체제에서도 구조체가 패킹되는 크기는 8 일 수 있다고 하네요! 디폴트 패킹 크기는 운영체제가 아닌 컴파일러가 결정하는 것이라 체계와 상관이 없고, char는 1의 배수, int 와 float은 4의 배수, double은 8의 배수의 메모리 주소를 가지는 것이 CPU가 접근하기 좋게 잘 정렬되있는 것이라고 합니다. 그래서 이렇게 패딩을 넣어 맞춰주는 듯 합니다.

1

네 저도 16byte 단위로 끊어진다면 질문자님께서 언급해주신

 | f  f  f  f o o o o d d d d d d d d | c o o o o o o o o o o o o o o o|

처럼 사이즈가 32 가 될 것이라고 저도 그렇게 예상을 했었는데 패킹 단위를 16byte 로 조정해도 사이즈는 24더라구요! (공식 문서에 따르면 x64의 디폴트 패킹단위가 16byte이니 x64로 실행해도 똑같이 24가 나오는 셈이 됩니다) 

16byte 단위로 패킹을 해도 사이즈가 24로 나온 것을 보면, 구조체 멤버 중 최대 자료형인 double에 맞춰서 남은 char 멤버가 있는 쪽은 8byte로  패킹 한 것이 아닐까.. 하고 추측하여 작성해본 답변이였습니다. ㅎㅎㅎ 제 추측이 틀렸을 수도 있습니다! 

1

저도 헷갈리네요 하하.. 😅 저도 질문자님의 질문을 보고 의문을 가지게 되었거든요 !

혹시 visual studio 설정에서 1 word당 크기 어떻게 바꾸신건지 알려주실 수 있을까요?

저도 다시 찾아보았는데요! 

https://docs.microsoft.com/en-us/cpp/build/reference/zp-struct-member-alignment?view=msvc-160&viewFallbackFrom=vs-2019

Visual Studio 공식 문서에 따르면 구조체 멤버들을 Packing 할 때 1, 2, 4, 8, 16 byte 단위로 멤버들을 묶을 수 있다고 합니다.

그 중에서도x64 체제일때의 디폴트는 구조체 멤버들을 16byte 단위로 묶는 것이고 x86 체제일때의 의 디폴트는 구조체 멤버들을 8byte 단위로 묶는 것이라고 하네요!  제가 답변으로 링크 드렸던 블로그에서도 32bit 체제에서도 구조체가 패킹되는 기본 크기는 8 이라고 했던 것과도 일맥상통해 보이네요. 그래서 질문자님께서 작성하신 코드가 x86과 x64에서 동일한 size를 보여줬던듯 합니다. 

제가 답변으로 드렸던 블로그에 따르면 각 자료형들은 자신의 크기의 배수의 메모리 주소를 가지는 것이 성능 상 좋으므로 질문자님의 코드에 따르면 ( o 는 패딩이라고 하겠습니다)

x64 에서는 16byte 단위로 묶여 👉  | f  f  f  f o o o o d d d d d d d d | c o o o o o o o | 👉 2 번 패킹

x32 에서는 8byte 단위로 묶여 👉  | f  f  f  f o o o o | d d d d d d d d | c o o o o o o o | 👉 3 번 패킹 

이렇게 묶여져서 24 라는 동일한 결과를 낳은게 아닐까 싶네요! (제 추측입니다)

이렇게 프로젝트 속성에서 - C/C++ - 코드 생성 - 구조체 멤버 맞춤에서 기본값에서 패킹을 4byte 로 바꿨더니 저 또한 size가 16으로 나왔습니다!! 😮 기본값이 8byte 인듯 합니다. ( x86상태에서의 속성 창입니다!)

공식 문서에서도 x86에서 디폴트로 8byte 단위 구조체 패킹이 이루어진다고 언급을 하고 있고 이렇게 비주얼 스튜디오 속성에서 구조체 멤버 패킹 단위도 다르게 설정할 수  있는 것을 보면 32bit 체제라고 해서 구조체 패킹도 4byte 단위로 이루어지는 것은 아닌듯 합니다. 기본 패킹 단위는 8byte인듯 하네요! 

명쾌하게 답을 드리지 못해 정말 정말 죄송합니다. 😭 저도 많이 헷갈리네요.. 그래도 조금이나마 도움 되셨으면 좋겠네요 ㅠ ㅠ 저도 개인적으로 정말 궁금해서 비주얼 스튜디오에서  1 word당 크기 어떻게 바꾸신건지 저도 알려주시면 감사하겠습니다! 

0

cjkoo96님의 프로필 이미지
cjkoo96
질문자

1 word 당 크기 조정한 것은 그 답변자분께서 사진 올려주신 창에서 조정한 것입니다ㅎㅎ

답변자분께서 올려주신 자료를 참고하니 충분히 답이 되었습니다. 감사합니다!!

그런데 답변자님 답변을 보고 궁금한게 생겼습니다. 

x64에서 1word 당 16bytes로 처리한다면 

"x64 에서는 👉  | f  f  f  f o o o o d d d d d d d d | c o o o o o o o | 👉 2 번 패킹"

여기서

| f  f  f  f o o o o d d d d d d d d | c o o o o o o o o o o o o o o o|

이렇게 처리되어 구조체 사이즈가 32가 되어야하는 것 아닌가요?

visual studio에서 1 word 당 16bytes로 하고 사이즈 찍어보면 답변자님 말씀처럼 24가 나오네요ㅠㅠ

혹시 최대 자료형인 double에 맞춰 패딩된 걸까요?

0

cjkoo96님의 프로필 이미지
cjkoo96
질문자

먼저 친절한 답변 정말 감사드립니다.

그런데 답변자분께서 설명해주신 데이터 타입에 의해 결정된다는 말씀에 약간 헷갈리는 부분이 있습니다.

제가 위에 작성한 코드를 visual studio의 설정에서 1word당 4bytes로 바꾼 후 돌려보니 size가 16이 나왔습니다. 분명 word당 byte에 따라서도 패딩에 차이가 있는 것 같다고 생각합니다. 

x86은 32bit체계로 1word당 4bytes여야하는데 설정에서 따로 만져주면 size가 16이 잘 나오고 default값으로 설정해놓으면 24가 나옵니다.

설정에서 1word당 byte 수를 변경하면 변경한 대로 구조체 변수가 패딩이 입혀지고, default로 설정했을 때는 구조체를 구성하는 변수들의 데이터 타입에 의해  결정된다고 이해하면 될까요?

cjkoo96님의 프로필 이미지
cjkoo96

작성한 질문수

질문하기