Game !

 

class 또는 struct 객체의 크기는 필드의 크기보다 크게 표시될 수 있다.

 

1
2
3
4
5
6
struct A
{
    public int i;           // 4
    public double d;        // 8
    public byte b;          // 1
}
cs

 

A 구조체의 경우, 크기를 4+8+1 = 13 으로 생각할 수 있지만,

실제 객체 사이즈를 확인해보면 24로 확인할 수 있다

 

* ex. Marshal.SizeOf( typeof( A ) )

 

왜냐면, C# / .NET 에서 자동으로 Field Ailgnment 규칙에 따라 객체 크기를 맞춘 것이다.

 

* C# / .NET 에서의 Field Ailgnment 규칙 : 8바이트 바운더리

-> 내 생각에, 2^n, 8^n 등 배수 규약에 맞춰지지 않은 크기여서, 특정 배수보다 크면 다음 배수 크기로 맞추는 규칙인듯.

 

 

그런데, 간혹 파일 스트림 등 바이트를 정확하게 읽어야하는 경우가 있을 수 있다. 

또는 메모리 필드 순서가 정확해야할 때가 있다. 

 

* 바이트를 정확하게 읽어야하는 경우 : 위의 예제대로 13바이트를 정확하게 가지고 있어야하는 경우

* 메모리 필드 순서가 정확해야할 때 : 메모리상에 i, d, b 위치가 정확해야할 때

-> 내 생각에, 객체 필드 변수를 메모리 파편화 등 막으려고 순서를 자동으로 변경하는듯

 

 

이럴 경우, 해당 방식들로 객체 크기를 고정시킬 수 있다

1
2
3
4
5
6
7
[StructLayOut(LayoutKind.Sequential, Pack = 1)]
struct A
{
    public int i;            // 4
    public double d;        // 8
    public byte b;            // 1
}
cs

 

---> Sequential :

실제 메모리에서는 변수 순서가 자동으로 변경되서 저장되지만,

객체의 변수를 가져와서 사용할 때는 반드시 변수 순서대로 데이터가 옮겨진다.

 

 

1
2
3
4
5
6
7
[StructLayOut(LayoutKind.Explicit, Pack = 1)]
struct A
{
    public int i;            // 4
    public double d;        // 8
    public byte b;            // 1
}
cs

 

---> Explicit :

실제 메모리 와 객체의 변수를 사용할 때 모두 변수를 순서대로 저장하고 읽는다는 것.

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
[StructLayOut(LayoutKind.Explicit, Pack = 1)]
struct A
{
    [FieldOffect(0)]    
    public int i;           // 4
 
    [FieldOffect(4)]    
    public double d;        // 8
 
    [FieldOffect(12)]    
    public byte b;          // 1
}
 
cs

 

Explicit 레이아웃을 사용할 경우, FieldOffset 키워드를 사용하여 특정 바이트 위치하게 할 수 있다.

해당 예제에서는 필드 변수 i 는 0번째에, d 는 4번째 바이트 위치하게 된다.

 

 

 

* ex. 응용의 경우 :

더보기
1
2
3
4
5
6
7
8
9
10
[StructLayOut(LayoutKind.Explicit, Pack = 1)]
struct A
{
    [FieldOffect(0)]    
    public int i;
 
    [FieldOffect(0)]    
    public float f;
}
 
cs

 

두 변수 모두 0번째 바이트에 위치 시킨다.

즉, i 에 값을 넣고, f 를 읽으면 i 값을 float 형으로 읽을 수 있다.

 

출처

http://csharpstudy.com/DevNote/Article/10

 

틀린 내용이 있으면 덧글 공유 부탁드립니다~

'C#' 카테고리의 다른 글

[C#] const, readonly 차이  (0) 2020.10.08
List<T>.RemoveAll(Predicate<T>) 함수 개념  (0) 2017.12.14