다음을 통해 공유


fixed 문 - 포인터 작업에 대한 변수 고정

이 문은 fixed가비지 수집 기가 이동 가능한 변수를 재배치하지 못하도록 하고 해당 변수에 대한 포인터를 선언합니다. 고정 또는 고정된 변수의 주소는 문을 실행하는 동안 변경되지 않습니다. 선언된 포인터는 해당 fixed 문 내에서만 사용할 수 있습니다. 선언된 포인터는 읽기 전용이며 수정할 수 없습니다.

unsafe
{
    byte[] bytes = [1, 2, 3];
    fixed (byte* pointerToFirst = bytes)
    {
        Console.WriteLine($"The address of the first array element: {(long)pointerToFirst:X}.");
        Console.WriteLine($"The value of the first array element: {*pointerToFirst}.");
    }
}
// Output is similar to:
// The address of the first array element: 2173F80B5C8.
// The value of the first array element: 1.

비고

안전하지 않은 컨텍스트에서만 문을 사용할 fixed 수 있습니다. 안전하지 않은 블록을 포함하는 코드는 AllowUnsafeBlocks 컴파일러 옵션으로 컴파일되어야 합니다.

다음과 같이 선언된 포인터를 초기화할 수 있습니다.

  • 이 문서의 시작 부분에 있는 예제와 같이 배열이 있습니다. 초기화된 포인터에는 첫 번째 배열 요소의 주소가 포함됩니다.

  • 변수의 주소를 사용합니다. 다음 예제와 같이 address-of & 연산자를 사용합니다.

    unsafe
    {
        int[] numbers = [10, 20, 30];
        fixed (int* toFirst = &numbers[0], toLast = &numbers[^1])
        {
            Console.WriteLine(toLast - toFirst);  // output: 2
        }
    }
    

    개체 필드는 고정할 수 있는 이동 가능한 변수의 또 다른 예입니다.

    초기화된 포인터에 개체 필드 또는 배열 요소 fixed 의 주소가 포함된 경우 문은 문 본문을 실행하는 동안 가비지 수집기가 포함하는 개체 인스턴스를 재배치하거나 삭제하지 않도록 보장합니다.

  • 라는 GetPinnableReference메서드를 구현하는 형식의 인스턴스를 사용합니다. 해당 메서드는 ref관리되지 않는 형식의 변수를 반환해야 합니다. .NET 형식 System.Span<T> 이며 System.ReadOnlySpan<T> 이 패턴을 사용합니다. 다음 예제와 같이 범위 인스턴스를 고정할 수 있습니다.

    unsafe
    {
        int[] numbers = [10, 20, 30, 40, 50];
        Span<int> interior = numbers.AsSpan()[1..^1];
        fixed (int* p = interior)
        {
            for (int i = 0; i < interior.Length; i++)
            {
                Console.Write(p[i]);  
            }
            // output: 203040
        }
    }
    

    자세한 내용은 API 참조를 Span<T>.GetPinnableReference() 참조하세요.

  • 다음 예제와 같이 문자열을 사용하여 다음을 수행합니다.

    unsafe
    {
        var message = "Hello!";
        fixed (char* p = message)
        {
            Console.WriteLine(*p);  // output: H
        }
    }
    
  • 고정 크기 버퍼를 사용하는 경우

가비지 수집의 대상이 아니므로 고정할 필요가 없는 스택에 메모리를 할당할 수 있습니다. 이렇게 하려면 식을 사용합니다stackalloc.

키워드를 fixed 사용하여 고정 크기 버퍼를 선언할 수도 있습니다.

C# 언어 사양

자세한 내용은 C# 언어 사양의 다음 섹션을 참조하세요.

참고하십시오