본문 바로가기

무언가 만들기 위한 지식/C,C++,Embedded C

[C] Structure 와 Union 형

술자리에서 대화소재거리가 떨어져 전공관련해서 쏼라쏼라를 하였다.
그때 아는 형님이 물어본 것이 int 2개와 char를 Structure로 만들어서 sizeof 하면 어떤 값이 출력되느냐이다.
생각없이 말해보니 4+4+1 이라고 대답을 했는데,
정답은 4+4+4이다. 예전 어셈블리언어 공부를 할때 경계정렬에 관하여 배웠던 것이 뇌리스치면서 기억이 떠올랐다.
이것과 관련하여 structure에 관련하여 테스트를 조금 해보았다.
(평소 이상하게시리 structure를 사용 안했다..... cpp의 클래스를 쓰면 썼지.......)
더불어 공용체라고 불리우는 union의 특징에 대해서도 테스트를 해보았다.

[작성환경 : Window XP   작성툴 : Visual Studio 6.0   컴파일러 : Visual Studio 6.0   사용언어 : C]


위 코드는 일단 struct와 union을 선언하여 sizeof로 그 크기를 출력해 본 것이다.
(struct 및 union 사용법은 지나가겠다. 전에 언급했으므로)
위 코드를 그대로 실행하면


위와 같은 결과가 나온다.
보통 struct의 경우 4+1+2=7 이라고 생각할지도 모른다. 하지만 위와 같이 메모리가 공간에 위치할때는 선언된 Type의 가장 큰 크기를 중심으로 Align이 이루어 진다. 위 코드 상에는 선언된 값들 중 int가 가장 큰 값이기 때문에 4byte를 중심으로 align이 이루어진다. 선언된 순서대로 메모리 구조를 보면


다음과 같다. 그러면 마지막 부분의 1byte가 사용되지 않는데도 정렬에 의하여 마지막 위치를 잡아 사용되게 된다.
그렇기 때문에 structure 자체를 sizeof를 하게되면 8 byte 가 나오게 된다.

그렇다면 다음과 같은 경우는 어떨까?


위와 같은 구조는 메모리 상에서는


위와 같이 나타난다. 즉 출력하면 총 16 byte가 사용되고 5 byte는 사용되지 않는다.
structure 내에서 정렬을 잘해주어야 한다. (컴파일러가 알아서 최적화 해주기는 할 것이다!)


추가적으로 double을 이용하면 align이 가장 큰 8 byte를 기준으로 이루어지게 된다.
위는 8 byte를 사용중이고 그 위로 8byte를 b, c, f를 사용되게 된다.


아래는 같은 4개의 변수를 위치만 조작해 본 것이다.
결과는 다른 크기인 16이 아닌 24 byte가 출력된다.


선언순에 따른 메모리 구조는 아래와 같다.


8 byte를 기준으로 공간이 잡히기 때문에 char b 선언부에서 쓸데없이 공간이 낭비된 모습을 볼 수 있다.
즉 이런 선언에서도 순서가 전체 크기에 신경이 쓰인다는 사실을 인지해야 한다.

이제 union이라는 공용체에 대해 알아보자.
일반적으로 변수는 그 형이 선언되면 선언된 형의 자료밖에는 취급할 수 없다.
그러나 두개 이상의 멤버를 동일한 주소가 가리키는 기억장치에 위치하게 할 수 있는데 그 경우 바로 union을 사용하면 된다.
나름대로 유동적인 자료를 취급하고자 할때 사용된다.
이 union의 특징은 위에서 처음 코드의 결과값으로 한번에 알 수 있다.
해당 Union을 sizeof하여 출력하면 가장 큰 자료형인 int형이 출력된 모습을 확인할 수 있다. (4 byte 출력)
가장 큰 자료형이 출력되는 이유는 다음과 같다.


union으로 선언을 하게되면 메모리상에 위와 같이 잡힌다.
특징으로는 내부적으로 선언된 변수 a, b, c의 시작 주소가 같은 값으로 시작되게 된다.
그렇기 때문에 union의 값으로 값을 기록하고(예를 들면 a에 5를 기록하고 c에 3을 기록하면 a의 값이 지워짐)
다시 쓰면 이전 값은 당연히 지워진다.
메모리의 시작 위치가 같기 때문이다.(파란색 부분
union형의 내부적으로 많은 변수 선언이 이루어져 있어도 결국 사용되는 메모리는 하나이다. 

유니온은 이런식으로 메모리구조가 이루어져 있기 때문에 가장 큰 Type을 총 메모리 크기로 잡아준다. 그렇기 때문에 sizeof로 출력을 하면 가장 큰 값이 그 크기로 나오게 된다.