구조체 메모리 할당 위치, 범위 고정시키기2021. 5. 11. 18:50
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
틀린 내용이 있으면 덧글 공유 부탁드립니다~
'Language > C#' 카테고리의 다른 글
C# 데이터 구조와 Object 타입 (0) | 2024.09.21 |
---|---|
c# Color 와 Color32 색상 범위 차이 (0) | 2020.10.20 |
[C#] const, readonly 차이 (0) | 2020.10.08 |
List<T>.RemoveAll(Predicate<T>) 함수 개념 (0) | 2017.12.14 |