57. [StructLayout]·MemoryMarshal 재해석·엔디안 (패킷 직렬화 함의)
난이도 상 해설 보기 →
결함을 모두 찾고 원인·수정안·더 나은 설계를 제시하라. 마커
(A)(B) 는 주목 위치 힌트다.
결함 코드 · C#
// 주제: [StructLayout] 필드 레이아웃과 MemoryMarshal 재해석, 엔디안 (패킷 직렬화 함의)
//
// 아래 프로그램의 출력을 예측하고, 다음을 설명하라:
// - LayoutKind.Explicit 와 FieldOffset 으로 겹치는(union 같은) 레이아웃이 어떻게 동작하는가.
// - int 를 바이트로 겹쳐 볼 때 나오는 순서가 왜 그런가(호스트 엔디안).
// - MemoryMarshal.Read<T> 가 바이트열을 어떻게 재해석하며, 왜 이식성 문제가 되는가.
// - Marshal.SizeOf 가 이 명시적 레이아웃에서 왜 그 값인가.
//
// 대상 런타임은 x86-64(리틀 엔디안)라고 가정한다.
//
// 과제:
// 1) 표준 출력을 한 줄씩 예측하라.
// 2) 게임 패킷을 구조체로 그대로 재해석(zero-copy)할 때의 위험(엔디안·정렬·패딩)을 논하라.
// 3) 네트워크 직렬화에서 MemoryMarshal.Read 대신 무엇을 써야 하는지 제시하라.
using System;
using System.Buffers.Binary;
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Explicit)]
public struct Overlap
{
[FieldOffset(0)] public int AsInt;
[FieldOffset(0)] public byte B0;
[FieldOffset(1)] public byte B1;
[FieldOffset(2)] public byte B2;
[FieldOffset(3)] public byte B3;
}
public class Program
{
public static void Main()
{
Overlap o = new Overlap();
o.AsInt = 0x04030201;
Console.WriteLine($"{o.B0} {o.B1} {o.B2} {o.B3}");
Console.WriteLine(BitConverter.IsLittleEndian);
byte[] buf = { 1, 2, 3, 4 };
int reinterpreted = MemoryMarshal.Read<int>(buf);
Console.WriteLine(reinterpreted);
int be = BinaryPrimitives.ReadInt32BigEndian(buf);
Console.WriteLine(be);
Console.WriteLine(Marshal.SizeOf<Overlap>());
}
} 내 리뷰 · C#
내 답안 · 자동 저장
작성 후 위 해설 보기에서 모범 해설과 대조하세요.