English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

C# 不安全コード

コードブロックが使用されている場合 危険 修飾子をマークすると、C#は関数内でポインタ変数を使用することが許可されます。不安全なコードまたは非メモリ管理コードは、ポインタ変数のブロックコード。

ポインタ変数

ポインタ は他の変数のアドレスを格納する値の変数であり、つまり、メモリ位置の直接アドレスです。他の変数や定数と同様に、他の変数のアドレスをポインタに格納する前に、ポインタを宣言する必要があります。

ポインタ変数の宣言の一般的な形式は次の通りです:

type* var-name;

以下はポインタ型の宣言の例です:

説明
int* pp は整数へのポインタです。
double* pp は双精度数へのポインタです。
float* pp は浮点数へのポインタです。
int** pp は整数へのポインタのポインタです。
int*[] pp は整数へのポインタの1次元配列です。
char* pp は文字へのポインタです。
void* pp は未知の型へのポインタです。

同じ宣言で複数のポインタを宣言する場合、アスタリスク * 基本的なデータ型とともにのみ書き込まれます;各ポインタ名の接頭辞として使用されません。例えば:

int* p1, p2, p3;     // 正しい  
int *p1, *p2, *p3;   // エラー

以下の例では、C#で修飾子が使用されています 危険 修飾子でのポインタの使用:

using System;
namespace UnsafeCodeApplication
{
    class Program
    {
        static unsafe void Main(string[] args)
        {
            int var = 20;
            int* p = &var;
            Console.WriteLine("データは:{0}", var);
            Console.WriteLine("アドレスは:{0}", (int)p);
            Console.ReadKey();
        }
    }
}

上記のコードがコンパイルおよび実行された場合、以下のような結果が得られます:

データは: 20
アドレスは: 99215364

安全なコードとして宣言する必要がない場合、メソッドの一部を安全なコードとして宣言するだけで十分です。以下の例がその点を示しています。

ポインタを使用してデータ値を検索する

次を使用できます ToString() メソッドはポインタ変数が参照する位置に格納されているデータを検索します。以下の例がその点を示しています:

using System;
namespace UnsafeCodeApplication
{
   class Program
   {
      public static void Main()
      {
         危険
         {
            int var = 20;
            int* p = &var;
            Console.WriteLine("データは:{0}", var);
            Console.WriteLine("データは:{0}", p->ToString());
            Console.WriteLine("アドレスは:{0}", (int)p);
         }
         Console.ReadKey();
      }
   }
}

上記のコードがコンパイルおよび実行された場合、以下のような結果が得られます:

データは: 20
データは: 20
アドレスは: 77128984

メソッドの引数としてポインタを渡す

メソッドにポインタ変数を引数として渡すことができます。以下の例がその点を示しています:

using System;
namespace UnsafeCodeApplication
{
   class TestPointer
   {
      public unsafe void swap(int* p, int *q)
      {
         int temp = *p;
         *p = *q;
         *q = temp;
      }
      public unsafe static void Main()
      {
         TestPointer p = new TestPointer();
         int var1 = 10;
         int var2 = 20;
         int* x = &var1;
         int* y = &var2;
         
         Console.WriteLine("Before Swap: var1:{0}, var2: {1}1, var2);
         p.swap(x, y);
         Console.WriteLine("After Swap: var1:{0}, var2: {1}1, var2);
         Console.ReadKey();
      }
   }
}

上記のコードがコンパイルおよび実行された場合、以下のような結果が得られます:

Before Swap: var1: 10, var2: 20
After Swap: var1: 20, var2: 10

ポインタを使用して配列要素にアクセス

C# では、配列名と配列データを持つ同じデータ型のポインタは異なる変数タイプです。例えば、int *p と int[] p は異なるタイプです。ポインタ変数 p はメモリ内で固定されていないため、増分できますが、配列のアドレスはメモリ内で固定されているため、配列 p を増分することはできません。

したがって、ポインタ変数を使用して配列データにアクセスする必要がある場合、CやC++で通常行うようにアクセスできます。++ と同じように、以下を使用して fixed キーワードでポインタを固定する。

以下の例ではこの点を示しています:

using System;
namespace UnsafeCodeApplication
{
   class TestPointer
   {
      public unsafe static void Main()
      {
         int[]  list = {10, 100, 200};
         fixed(int *ptr = list)
         /* ポインタ内の配列アドレスを表示 */
         for ( int i = 0; i < 3; i++)
         {
            Console.WriteLine("list[{0}]のアドレス={1} + i));
            Console.WriteLine("list[{0}]の値={1} *(ptr + i));
         }
         Console.ReadKey();
      }
   }
}

上記のコードがコンパイルおよび実行された場合、以下のような結果が得られます:

list[0]のアドレス 31627168
list[0]の値 10
list[のアドレス1] = 31627172
list[の値1] = 100
list[のアドレス2] = 31627176
list[の値2] = 200

危険なコードのコンパイル

危険なコードをコンパイルするために、コマンドラインコンパイラに切り替える必要があります。 /危険 コマンドライン。

例えば、不安全コードを含むプログラムprogをコンパイルするために1.csのプログラム、コマンドラインで以下のコマンドを入力します:

csc /unsafe prog1.cs

Visual Studio IDEを使用している場合、プロジェクトプロパティで不安全コードを有効にする必要があります。

手順は以下の通りです:

  • リソース管理器(ソリューションエクスプローラー)のプロパティ(プロパティ)ノードをダブルクリックして開きます。プロジェクトプロパティ(プロジェクトプロパティ)

  • クリック ビルド タブ

  • 選択オプション「"不安全コードの許可「。