Zeiger und unsicherer Code

Zeiger und unsicherer Code

# Einführung in unsicheren Code

C# erlaubt die Verwendung von Zeigervariablen in einer Funktion eines Codeblocks, wenn er durch unsafe gekennzeichnet ist Modifikator. Der unsichere Code oder der nicht verwaltete Code ist ein Codeblock, der eine Zeigervariable verwendet.

Ein Zeiger ist eine Variable, deren Wert die Adresse einer anderen Variablen ist, d. h. die direkte Adresse des Speicherplatzes. Ähnlich wie bei jeder Variablen oder Konstante müssen Sie einen Zeiger deklarieren, bevor Sie ihn zum Speichern einer Variablenadresse verwenden können.

Die allgemeine Form einer Zeigerdeklaration ist:

type *var-name;

Es folgen gültige Zeigerdeklarationen:

int    *ip;    /* pointer to an integer */
double *dp;    /* pointer to a double */
float  *fp;    /* pointer to a float */
char   *ch     /* pointer to a character */

Das folgende Beispiel veranschaulicht die Verwendung von Zeigern in C# mit dem unsafe-Modifizierer:

using System;
namespace UnsafeCodeApplication
{
   class Program
   {
      static unsafe void Main(string[] args)
      {
         int var = 20;
         int* p = &var;
         Console.WriteLine("Data is: {0} ",  var);
         Console.WriteLine("Address is: {0}",  (int)p);
         Console.ReadKey();
      }
   }
}

Wenn der obige Code kompiliert und ausgeführt wurde, erzeugt er das folgende Ergebnis:

Data is: 20
Address is: 99215364

Anstatt eine ganze Methode als unsicher zu deklarieren, können Sie auch einen Teil des Codes als unsicher deklarieren:

// safe code
unsafe
{
    // you can use pointers here
}
// safe code

# Zugriff auf Array-Elemente mit einem Zeiger

In C# sind ein Arrayname und ein Zeiger auf einen Datentyp, der den Arraydaten entspricht, nicht derselbe Variablentyp. Beispiel:int *p und int[] p , sind nicht vom gleichen Typ. Sie können die Zeigervariable p inkrementieren weil es nicht im Speicher fixiert ist, sondern eine Array-Adresse im Speicher fixiert ist und Sie diese nicht inkrementieren können.

Wenn Sie also mit einer Zeigervariablen auf Array-Daten zugreifen müssen, wie wir es traditionell in C oder C++ tun, müssen Sie den Zeiger mit dem Schlüsselwort fixed fixieren.

Das folgende Beispiel demonstriert dies:

using System;
namespace UnsafeCodeApplication
{
   class TestPointer
   {
      public unsafe static void Main()
      {
         int[]  list = {10, 100, 200};
         fixed(int *ptr = list)
         
         /* let us have array address in pointer */
         for ( int i = 0; i < 3; i++)
         {
            Console.WriteLine("Address of list[{0}]={1}",i,(int)(ptr + i));
            Console.WriteLine("Value of list[{0}]={1}", i, *(ptr + i));
         }
         
         Console.ReadKey();
      }
   }
}

Wenn der obige Code kompiliert und ausgeführt wurde, erzeugt er das folgende Ergebnis:

Address of list[0] = 31627168
Value of list[0] = 10
Address of list[1] = 31627172
Value of list[1] = 100
Address of list[2] = 31627176
Value of list[2] = 200

# Unsicherer Code wird kompiliert

Zum Kompilieren von unsicherem Code müssen Sie den /unsafe angeben Befehlszeilenschalter mit Befehlszeilencompiler.

Um beispielsweise ein Programm namens prog1.cs zu kompilieren, das unsicheren Code enthält, geben Sie in der Befehlszeile den folgenden Befehl ein:

csc /unsafe prog1.cs

Wenn Sie Visual Studio IDE verwenden, müssen Sie die Verwendung von unsicherem Code in den Projekteigenschaften aktivieren.

Dazu:

  • Öffnen Sie die Projekteigenschaften, indem Sie im Projektmappen-Explorer auf den Eigenschaftenknoten doppelklicken.
  • - Klicken Sie auf die Registerkarte Bauen.
  • Wählen Sie die Option „Unsicheren Code zulassen“
  • # Abrufen des Datenwerts mit einem Zeiger

    Sie können die Daten abrufen, die an dem Ort gespeichert sind, auf den durch die Zeigervariable verwiesen wird, indem Sie die Methode ToString() verwenden. Das folgende Beispiel demonstriert dies:

    using System;
    namespace UnsafeCodeApplication
    {
       class Program
       {
          public static void Main()
          {
             unsafe
             {
                int var = 20;
                int* p = &var;
                Console.WriteLine("Data is: {0} " , var);
                Console.WriteLine("Data is: {0} " , p->ToString());
                Console.WriteLine("Address is: {0} " , (int)p);
             }
             
             Console.ReadKey();
          }
       }
    }
    
    

    Wenn der obige Code kompiliert und ausgeführt wurde, erzeugt er das folgende Ergebnis:

    Data is: 20
    Data is: 20
    Address is: 77128984
    
    

    # Übergabe von Zeigern als Parameter an Methoden

    Sie können einer Methode eine Zeigervariable als Parameter übergeben. Das folgende Beispiel veranschaulicht dies:

    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}", var1, var2);
             p.swap(x, y);
    
             Console.WriteLine("After Swap: var1:{0}, var2: {1}", var1, var2);
             Console.ReadKey();
          }
       }
    }
    
    

    Wenn der obige Code kompiliert und ausgeführt wird, erzeugt er das folgende Ergebnis:

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

    No