2010-05-21 2 views
21

7 바이트 (또는 3 또는 777)의 값 유형을 원한다고 가정 해 봅시다.고정 크기 버퍼 (배열)가 안전하지 않은 이유는 무엇입니까?

I는 그런 식으로 정의 할 수

public struct Buffer71 
{ 
    public byte b0; 
    public byte b1; 
    public byte b2; 
    public byte b3; 
    public byte b4; 
    public byte b5; 
    public byte b6; 
} 

를 정의하는 간단한 방법 것은 고정 버퍼 물론

public struct Buffer72 
{ 
    public unsafe fixed byte bs[7]; 
} 

번째 정의 간단를 사용한다. 고정 버퍼에 제공되어야하는 안전하지 않은 키워드와 관련된 문제점이 있습니다. 나는 이것이 포인터를 사용하여 구현되어 안전하지 못하다는 것을 이해한다.

내 질문에 왜 안전하지 않아야합니까? C#이 임의의 상수 길이 배열을 제공하고 C# 참조 형식 배열 또는 안전하지 않은 버퍼로 만드는 대신 값 형식으로 유지할 수없는 이유는 무엇입니까?

답변

13

"고정 버퍼"가 실제 배열이 아니기 때문에. 내가 아는 C# 언어로 생성하는 유일한 방법 인 사용자 지정 값 형식입니다. CLR이 배열의 색인 생성이 안전한 방법으로 수행되는지 확인할 수있는 방법은 없습니다. 코드도 검증 할 수 없습니다. 이 가장 그래픽 데모 :

using System; 

class Program { 
    static unsafe void Main(string[] args) { 
     var buf = new Buffer72(); 
     Console.WriteLine(buf.bs[8]); 
     Console.ReadLine(); 
    } 
} 
public struct Buffer72 { 
    public unsafe fixed byte bs[7]; 
} 

이 예제에서는 임의로 스택 프레임에 액세스 할 수 있습니다. 표준 버퍼 오버 플로우 주입 기술은 악의적 인 코드가 함수 반환 주소를 패치하고 코드가 임의의 위치로 이동하도록 할 수 있습니다.

예, 안전하지 않습니다.

+11

CIL에 바운딩 된 인덱스 작업을 수행하는 방법이 없다는 문제가 있습니까? CIL이 그러한 기능을 제공 할 수 없다는 의미 론적 이유는 전혀 없습니다. 그래픽 변환과 같은 것들은 구조체의 "이상적인"16 바이트 크기에 비해 약간있을 수 있지만 논리적으로 가변 값 의미를 가져야합니다. 불변의 시맨틱은 인스턴스 내의 값을 조정하는 것을 어렵게 만들고, 가변적 인 참조 시맨틱은 예를 들어, 인스턴스를 반환하는 함수는 새 인스턴스 또는 기존 인스턴스를 반환합니다. – supercat

+0

그다지 간단하지 않아 동시 안전 보장과 관련된 많은 문제를 야기합니다. – user1496062

+1

구조체에 고정 된 크기의 배열을 임베드하는 * 안전한 * 방법이 없다는 것이 제정신이 아닙니다. 코드의 고성능 섹션에서는 100 % blittable 구조체 만 사용하고 싶습니다. 최소한 우리는 지금 심판 검사 결과를 가지고 있습니다. – JBeurer