# アンセーフな配列の使用
ポインターを使用して配列にアクセスする場合、境界チェックがないため、IndexOutOfRangeException
はありません。 投げられます。これにより、コードが高速になります。
ポインターを使用して配列に値を割り当てる:
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;
}
}
}
安全でない部分は一般に高速であり、パフォーマンスの違いは、配列内の要素の複雑さと各要素に適用されるロジックによって異なります。高速かもしれませんが、保守が難しく、破損しやすいため、注意して使用する必要があります。
# unsafe を文字列で使用する
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"
# 安全でない配列インデックス
void Main()
{
unsafe
{
int[] a = {1, 2, 3};
fixed(int* b = a)
{
Console.WriteLine(b[4]);
}
}
}
このコードを実行すると、長さ 3 の配列が作成されますが、5 番目の項目 (インデックス 4) を取得しようとします。私のマシンでは、これは 1910457872
を出力しました 、しかし動作は定義されていません。
unsafe
なし ブロックでは、ポインターを使用できないため、例外をスローせずに配列の末尾を超える値にアクセスすることはできません。
# コメント
unsafe
を使用できるようにするため .Net プロジェクトのキーワードの場合、プロジェクト プロパティ => ビルドで「安全でないコードを許可する」をチェックする必要があります- アンセーフ コードを使用するとパフォーマンスが向上しますが、コードの安全性が犠牲になります (したがって、
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;
}
}
}