문제

아래 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;
    }
}
도움이 되었습니까?

해결책

에릭은 옳지 만, 당신이 듣고 싶은 대답은 "때로는 고정 진술 외부의 주소를 유지하는 것이 유용하다"는 것입니다.

어쩌면 해당 포인터의 메모리는 이미 다른 고정 된 진술에 의해 이미 고정되어 있고 그것을 반환하는 것이 합리적입니까? 컴파일러는 당신을 두 번째로 추측하고 시끄러운 경고를 주려고하지 않습니다.

즉, CodeAnalysis 또는 기타 고급 도구가 컴파일러가 자신의 발을 차단할 수 있도록 여기에 들어올 수 있기를 바랍니다.

다른 팁

기억이 해방된다고해서 글을 쓰는 것이 어떤 종류의 오류를 일으킬 것이라는 것을 의미하지는 않습니다. 쓰레기 수집가가 메모리를 되 찾으면 내부 메모리 맵에서 메모리를 자유롭게 표시합니다. 즉시 OS로 돌려주지 않으므로 프로세스를 사용하는 데 여전히 유효한 메모리입니다.

물론 고정 블록 외부에서 포인터를 사용하는 것은 매우 나쁜 생각 -하지 마십시오.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top