C# Struct의 메모리 레이아웃 문제 해결
struct Struct1
{
public byte a;
public short b;
public string c;
public int d;
}
struct Struct2
{
public byte a;
public long b;
public byte c;
public string d;
}
struct Struct3
{
byte a;
byte b;
long c;
}
struct Struct4
{
byte a;
long b;
byte c;
}
이따가 답을 보고 너의 이해와 큰 차이가 있는지 확인해 볼까?사실 struct와class의 메모리 레이아웃은 모두 Struct Layout Attribute의 구조 매개 변수입니다: Layout Kind 매거진에 의해 결정되고 struct는 컴파일러에 Layout Kind를 추가합니다.Sequential,class는 컴파일러에 Layout Kind를 추가합니다.Auto.Sequential은 실험 데이터를 통해 다음과 같이 요약할 수 있습니다.
1. 인용 형식이 없는 struct: 정의된 순서에 따라 배열하고 메모리 레이아웃은 c, c++ 규칙과 같습니다.예를 들면 다음과 같습니다.
Byte a;
Byte b;
Long c;
의 크기는 a, b는 4 바이트, c는 8 바이트입니다.
Byte a
Long c
Byte b
의 크기는 a 충전 8 바이트, c 충전 8 바이트, b 충전 8 바이트입니다.
2. 인용 형식이 있는 struct: 4바이트 이상의 필드 -> 인용 필드 -> 4바이트 이하의 필드
4바이트 이하의 필드는 크기에 따라 배열되며, 크기가 같으면 정의 순서에 따라 메모리 레이아웃과 규칙 1이 같습니다.그러나 여기서 주의해야 할 점은 필드가 struct 형식이라면 이 필드는 항상 맨 뒤에 있다는 것이다.
그래서 위의 답은:
Struct1:c(4) -> d(4) -> b(2) ->a(2)
Struct2:b(8)-> d(4)-> a(1)c(1) 2바이트 채우기
Struct3: a(1)b(1) 2바이트 채우기-> c(8)
Struct4: a(1) 7바이트 채우기->b(8)->c(1) 7바이트 채우기
직접 실험을 해보고 싶다면 SOS를 사용해야 한다.dll에서 디버깅 (SOS 설정과 입문에 관한 글이 블로그에 많음) 을 진행합니다. struct1을 예로 들면 다음과 같습니다.
Struct1s1 = new Struct1();
s1.a = 1;
s1.b = 15;
s1.c = "c";
s1.d = 32;
.load sos
확장 C:\WINDOWS\Microsoft가 로드되었습니다.NET\Framework\v2.0.50727\sos.dll
!clrstack -a
PDB symbol for mscorwks.dll not loaded
OS Thread Id: 0x15fc (5628)
ESP EIP
0041ee3c 03ba01aa Test_Console.Class12.Main()
LOCALS:
0x0041ee84 = 0x01b02b0c
0x0041ee74 = 0x00000020
0x0041ee68 = 0x00000000
0x0041ee50 = 0x00000000
0041f104 6ebd1b4c [GCFrame: 0041f104]
.load sos
확장 C:\WINDOWS\Microsoft가 로드되었습니다.NET\Framework\v2.0.50727\sos.dll
!name2ee *!Test_Console.Struct1//Struct1의 메소드 테이블 주소 가져오기
PDB symbol for mscorwks.dll not loaded
Module: 6d5d1000 (mscorlib.dll)
--------------------------------------
Module: 00192c5c (Test_Console.exe)
Token: 0x02000012
MethodTable: 00193828
EEClass: 007a45b4
Name: Test_Console.Struct1
!clrstack -a//struct1 실례의 창고 주소
OS Thread Id: 0x1438 (5176)
ESP EIP
003eef0c 008f00c9 Test_Console.Class12.Main()
LOCALS:
0x003eef1c = 0x01c12b0c
003ef17c 6ebd1b4c [GCFrame: 003ef17c]
!dumpvc00193828 0x003eef1c//보기 값 형식의layout
Name: Test_Console.Struct1
MethodTable 00193828
EEClass: 007a45b4
Size: 20(0x14) bytes
Fields:
MT Field Offset Type VT Attr Value Name
6d84340c 400001c a System.Byte 1 instance 1 a
6d83e910 400001d 8 System.Int16 1 instance 15 b
6d8408ec 400001e 0 System.String 0 instance 01c12b0c c
6d842b38 400001f 4 System.Int32 1 instance 32 d
메모리 창에는 다음과 같은 메모리 레이아웃이 표시됩니다.
0x003EEF1C 01c12b0c 00000020 0001000f
여기에dumpvc를 사용한 후에 하나의 사이즈를 보여 드리겠습니다. 여기는 20바이트입니다. 우리가 계산한 결과보다 8바이트가 더 많습니다. 인용 유형에 추가된 8바이트(syncblkindex+methodtableaddress)가 있기 때문에 여기의 사이즈도 8.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.