Creative Commons License

Microsoft .NET

닷넷!시작하기
닷넷! Ver 2.0~
닷넷!스킬업
웹개발
윈폼개발
실용모듈개발
Tip & Tech
하루 한 문법

Microsoft .NET 개발자들을 위한 공간입니다. 기초강의에서 부터 고급 기술 정보 및 팁등을 다루도록 하겠습니다.

.

닷넷!시작하기

Microsoft. NET 을 시작하는 분들을 위한 강좌입니다. 주로 기초적인 내용과 때론 기본적인 내용을 다룹니다

닷넷에서 공용체 사용하기

작성자 : 박종명
최초 작성일 : 2009-10-29 (목요일)
최종 수정일 : 2009-10-29 (목요일)
조회 수 : 3901

C 또는 C++ 언어에서는 공용체라는 것이 있습니다

구조체와 유사하지만, 메모리 할당 측면이 조금 다르죠

C 문법으로,
구조체는 struce , 공용체는 union 키워드를 사용하여 정의합니다

구조체는 멤버들의 타입에 따라 메모리 공간이 각각 할당되지만,
공용체는 멤버들이 메모리 공간을 공용으로 사용하게 됩니다

아래 구조체의 경우 int 타입의 멤버가 2개 정의되어 있습니다
int 는 4byte 메모리 공간을 차지하기에 i, j 모두 각각 메모리를 할당받게 되어 총 8byte 의 크기를 가지게 됩니다

//구조체 정의
struct MyStruct1
{        
      public int i;
      public double j;        
}

//구조체 크기
System.Runtime.InteropServices.Marshal.SizeOf(typeof(MyStruct1)); // 8 반환

그러나 공용체의 경우는 다릅니다
C에서는 union 을 통해 공용체를 정의할 수 있지만, C#에서는 특별히 공용체라는 타입이 존재하지는 않습니다

다만 구조체의 멤버들의 레이아웃을 명시적으로 지정할 수 있도록 하는데, 이 방식을 이용해 공용체를 정의할 수
있습니다.

닷넷 프레임웍의 StructLayoutAttribute 특성을 이용하면 구조체 멤버들의 레이아웃을 제어할 수 있습니다
보통 StructLayoutAttribute 특성은 닷넷에서 C++과 같은 비관리코드에 구조체를 전송할 경우 많이 사용하게 됩니다

다음 코드는 구조체를 공용체로 만드는 코드 입니다

[System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Explicit)]
struct MyStruct2
{
     [System.Runtime.InteropServices.FieldOffset(0)]
     public int i;

     [System.Runtime.InteropServices.FieldOffset(0)]
     public int j;
}

LayoutKind.Explicit 를 지정하여 구조체의 각 멤버들의 위치를 명시적으로 제어하도록 하며,
i 와 j 의 시작 위치를 둘다 0으로 지정하면, 같은 메모리 영역을 사용하게 됩니다(즉 공용체이죠)


이렇게 정의된 구조체(공용체)의 사이즈(size)를 아래의 코드로 확인하면 4 byte 임을 알 수 있습니다

System.Runtime.InteropServices.Marshal.SizeOf(typeof(MyStruct2)); // 4 반환

즉, int 타입 멤버 i, j 가 4byte 메모리 공간을 공유하게 되는 것입니다

만일 j 가 double 타입이라면, 공용체의 크기는 8byte 가 됩니다. 다시말해 공용체의 경우 멤버들 중 가장 큰 타입의 크기가 할당되게 됩니다

메모리가 공유되는 것을 확인하기 위해 다음의 코드를 확인해 보세요

MyStruct2 myStruct2 = new MyStruct2();
myStruct2.i = 10;
myStruct2.j = 20;

Console.WriteLine(myStruct2.i); // i 의 값이 무엇일까요?

분명 i 에 10을 지정했지만 결과는 20입니다. 즉 나중에 할당된 j 값이 i 의 값을 덮어 써버리게 된 것입니다

다만, 여기서 중요한 것은 i 값이 20이라는 것이 아니라, 메모리가 공유된다는 것이며 공유된 상태에서 다른 값은
무의미하다는 것입니다. 실제로 예제에서,  j 의 타입이 double 였다면 i 값은 20이 아니라 0 이 됩니다.
즉 덮어쓰진 멤버값은 참조할 가치가 없는 쓰레기 값이라고 생각하면 됩니다

이름
비밀번호
홈페이지
WI <- 왼쪽의 문자를 오른쪽 박스에 똑같이 입력해 주세요