2009-05-14 2 views
0

아래의 C# 코드가 충돌하지 않는 이유를 설명 할 수 있습니까? Visual Studio에서 실제로 컴파일 할 수있는 이유는 무엇입니까? 내 이해는 내가 고정 포인터를 얻고있다지만, 그것은 '고정'성명 내에서만 수정됩니다. 포인터가 'Foo'함수에서 리턴되면 배열 'ar'이 수집 될 수 있습니다. 그런 다음 GC가 실제로이 작업을하도록 강요하지만, 메모리에 연속적으로 쓰면 (할당이 취소됨) 오류가 발생하지 않습니다.고정 된 문장 외부의 고정 된 포인터의 명확하지 않은 동작

class Program 
{ 
    static unsafe byte* Foo() 
    { 
     byte[] ar = new byte[100]; 
     fixed (byte* ptr = ar) 
     { 
      return ptr; 
     } 
    } 

    static unsafe void Main(string[] args) 
    { 
     byte* ptr = Foo(); 
     GC.Collect(); 
     for (int t = 0;;++t) ptr[t%100] = 0; 
    } 
} 

답변

1

에릭 (Eric)이 맞지만, "고정 진술 외의 주소를 유지하는 것이 유용합니다"라는 대답을 듣고 싶을 수도 있습니다.

어쩌면 그 포인터의 메모리가 다른 고정 된 명령문에 의해 이미 고쳐져 있고 그것을 반환하는 것이 맞습니까? 컴파일러는 당신을 추측하고 시끄러운 경고를하기 위해 노력하지 않습니다.

그렇다면 컴파일러가 자신의 발을 자르고있는 곳에서 CodeAnalysis 또는 다른 고급 도구가 도움이되기를 바랍니다.

1

메모리가 해제 되었기 때문에 그 메모리에 기록하는 것이 어떤 종류의 오류를 발생시키는 것은 아닙니다. 가비지 컬렉터가 메모리를 회수 할 때 내부 메모리 맵에 무료로 표시합니다. 즉, OS에 즉시 반환하지 않으므로 사용하는 프로세스에 여전히 유효한 메모리입니다.

물론 고정 된 블록 외부의 포인터를 사용하면 은 매우입니다.하지 마세요.

+0

하지만 컴파일 타임 오류가 발생하지 않은 이유는 무엇입니까? 확실한 오류라면 컴파일러가 오류 메시지를 생성해야한다고 생각합니다. –

+2

"안전하지 않은"부분을 확인 하시겠습니까? 컴파일러에게 "내가하는 일을 알고이 위험한 코드의 유형 안전에 대한 책임을지고 있습니다"라고 말한 것입니다. 컴파일러는 자신이하는 일을 알고 있다고 말했을 때 자신을 믿기 때문에 경고하지 않습니다. –

관련 문제