サーチ…


備考

  • .Netプロジェクトでunsafeキーワードを使用できるようにするには、Project Properties => Buildで「安全でないコードを許可する」チェックボックスをオンにする必要があります
  • 安全でないコードを使用すると、パフォーマンスが向上する可能性がありますが、コードの安全性を犠牲にしています(したがって、 unsafeという用語)。

たとえば、forループを使用すると、次のような配列が生成されます。

for (int i = 0; i < array.Length; i++)
{
    array[i] = 0;
}

.NET Frameworkでは、配列の境界を超えないように、インデックスが境界を超えた場合にIndexOutOfRangeExceptionします。

しかし、安全でないコードを使用すると、配列の境界を超えてしまうことがあります:

unsafe
{
    fixed (int* ptr = array)
    {
        for (int i = 0; i <= array.Length; i++)
        {
            *(ptr+i) = 0;
        }
    }
}

安全でない配列インデックス

void Main()
{
    unsafe
    {
        int[] a = {1, 2, 3};
        fixed(int* b = a)
        {
            Console.WriteLine(b[4]);
        }
    }
}

このコードを実行すると長さ3の配列が作成されますが、次に5番目の項目(インデックス4)を取得しようとします。私のマシンでは、これは1910457872印刷し1910457872が、その動作は定義されていません。

unsafeブロックがなければ、ポインタを使用することはできません。そのため、配列の末尾を超えて値にアクセスすることはできません。例外がスローされることはありません。

安全でない配列の使用

ポインタで配列にアクセスすると、境界チェックがないため、 IndexOutOfRangeExceptionIndexOutOfRangeExceptionされません。これにより、コードが高速になります。

ポインタを使って配列に値を代入する:

class Program
{
    static void Main(string[] args)
    {
        unsafe
        {
            int[] array = new int[1000]; 
            fixed (int* ptr = array)
            {
                for (int i = 0; i < array.Length; i++)
                {
                    *(ptr+i) = i; //assigning the value with the pointer
                }
            }
        }
    }
}

安全で正常な相手は次のようになります。

class Program
{
    static void Main(string[] args)
    {            
        int[] array = new int[1000]; 

        for (int i = 0; i < array.Length; i++)
        {
            array[i] = i;
        }
    }
}

安全でない部分は一般的に高速で、性能の差はアレイの要素の複雑さと、それぞれのロジックに適用されるロジックによって異なります。より速いかもしれませんが、維持することは難しく、壊れやすいので、注意して使用する必要があります。

安全でない文字列を使う

var s = "Hello";      // The string referenced by variable 's' is normally immutable, but
                      // since it is memory, we could change it if we can access it in an 
                      // unsafe way.

unsafe                // allows writing to memory; methods on System.String don't allow this
{
  fixed (char* c = s) // get pointer to string originally stored in read only memory
    for (int i = 0; i < s.Length; i++)
      c[i] = 'a';     // change data in memory allocated for original string "Hello"
}
Console.WriteLine(s); // The variable 's' still refers to the same System.String
                      // value in memory, but the contents at that location were 
                      // changed by the unsafe write above.
                      // Displays: "aaaaa"


Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow