unsafe 문맥에서 포인터를 사용할 수 있는 것은 스택에 데이터가 저장된 변수에 한해 적용된다.

즉, 지역 변수나 메서드의 매개변수 타입이 값 형식 경우에만 포인터 연산자(*, &)를 사용할 수 있다.

반면 참조 형식의 데이터는 직접적인 포인터 연산을 지원할 수 없다. 왜냐하면 참조 형식의 인스턴스

는 힙에 할당되고 그 데이터는 가비지 수집기가 동작할 때마다 위치가 바뀔 수 있기 때문이다. 이로

인해 포인터를 이용해 그 위치를 가리키면 가비지 수집 이후 엉뚱한 메모리를 가리킬 수 있다는 위험

이 따른다. 바로 이런 문제를 해결하기 위해 C#에는 fixed라는 예약어를 도입했다. fixed 예약어가

하는 정확한 역할은 힙에 할당된 참조 형식의 인스턴스를 가비지 수집기가 움직이지 못하도록 고정

시킴으로써 포인터가 가리키는 메모리를 유효하게 만드는 것이다. 다음은 이를 보여주는 예제다.

using System;

class Managed
{
		public int Count;
		public string Name;
}

class Program
{
		unsafe static void Main(string[] args)
		{
				Managed inst = new Managed();

				inst.Count = 5;
				inst.Name = "text";

				fixed (int* pValue = &inst.Count)
				{
						*pValue = 6;
				}

				fixed (char* pChar = inst.Name.ToCharArray())
				{
						for (int i = 0; i < inst.Name.Length; i++)
						{
								Console.WriteLine(*(pChar + i));
						}
				}
		}
}

Managed 타입의 객체인 inst 변수에 대해 직접 포인터를 가져오지 않았다는 점에 유의할 필요가

있다. C#은 객체 인스턴스의 포인터를 가져오는 것을 허용하지 않는다. 대신 해당 객체가 가진 멤버

데이터가 값 형식이거나 값 형식의 배열인 경우에만 포인터 연산을 할 수 있다. 하지만 fixed되는

대상은 객체의 데이터를 포함한 객체가 된다. 따라서 프로그램 실행이 fixed 블록의 끝에 다다를 때까

지는 가비지 수집기가 해당 객체를 이동시킬 수 없다.

보통 fixed된 포인터는 관리 프로그램의 힙에 할당된 데이터를 관리되지 않은 프로그램에 넘기는

용도로 쓰인다.