unsafe1 Articles

  1. 2006/12/20 unsafe와 fixed
C# 2006/12/20 15:13

unsafe와 fixed

unsafe 키워드를 알아 보자

일반적으로 C#에서는 CLR이라는 놈이 메모리를 관리 해주기 때문에 메모리에 신경을 별로 쓰지 않아도 알아서 다 해준다. 그렇기 때문에 포인터 처리 차체를 기본적으로 처리 하지 않느다. 그래서 일반적인 C의 * 요놈이나 & 요놈이 처리 되지 않는다. 그런데 그렇다고 포인터 연산을 사용할수 없지는 않는단다.(전혀 몰라던 사실 ㅜㅜ)
CLR이 메모리를 관리 해주면 안전하지만 사람이 관리 하면 불안전해서 붙여진 이름인가 보다 unsafe 라는 키워드 이 키워드를 사용하면 C의 포인터를 처리 할수 있다.


using System;
class UnsafeTest2
{
unsafe static void Swap(int *x,int *y)
{
int temp;
temp = *x;
*x = *y;
*y = temp;
}
public static void Main()
{
int x = 10;
int y = 20;
Console.WriteLine("Swap Before x:{0} y:{1}",x,y);
unsafe
{
  Swap(&x,&y);
}
Console.WriteLine("Swap After x:{0} y:{1}",x,y);
}
}
 

csc /unsafe UnsafeTest.cs

UnsafeTest
Swap Before x:10 y:20
Swap After x:20 y:10


위의 소스를 보게 되면 unsafe로 선언된 함수나 구역에서는 포인터 처리를 할 수 있다. 음. 여태껏 몰랐던 사실이다. 그리고 컴파일 할 때는 옵션으로 /unsafe 라는 옵션을 넣어 주어야 한다. 그렇지 않으면 Error가 난다.

다음으로 fixed이다. 일단 이 fixed란 놈은 unsafe코드 영역 내부에서 사용되어 진다. 그런데 어떨때 사용되나? 이 fixed라는 놈은 포인터의 값으로 배열이나 혹은 클래스의 멤버를 넘겨 줄수도 있을 것이다. 그런데 일반적인 unsafe문 안에서라도 클래스의 주소를 바로 넘겨 버리면 값을 넘겨주지 못한다. 이런 황당 씨츄에이션이 ㅡ.ㅡ; 어째던 배열이나 클래스 멤버의 주소를 넘겨 줄려면 fixed를 사용해서 값을 넘겨 준다.


using System;
class Point
{
public int x,y;
}
class FixedTest2
{
unsafe static void DoubleSum(int *p)
{
 int a = *p;
 *p = a+a;
}
unsafe static void Main()
{
 Point pt = new Point();
 pt.x = 5;
 pt.y = 6;
 fixed(int *p = &pt.x)
 {
  DoubleSum(p);
 }
 Console.WriteLine("{0} {1}",pt.x,pt.y);
}
}
 



위와 같이 클래스의 멤버 변수 x를 접근 할려고 할때 fixed를 사용하게 된다. 그런데 fixed를 사용하지 않고
DoubleSum(&pt.x); 라고 바로 값을 넘겨 줄 경우

csc /unsafe FixedTest2.cs
Microsoft (R) Visual C# 2005 Compiler version 8.00.50727.42 for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727 Copyright (C) Microsoft Corporation 2001-2005. All rights reserved.

FixedTest2.cs(21,13): error CS0212: 고정되지 않은 식의 주소는 fixed 문의
       이니셜라이저를 통해서만 가져올 수 있습니다.



위와 같은 에러가 나게 된다. 아마도 CLR이 접근 구성하느 배열 혹은 클래스의 메모리를 C의 스타일대로 접근하려 할때 사용되는 것을 알게 되었다.


div>