C # - Codici non sicuri

C # consente di utilizzare le variabili del puntatore in una funzione del blocco di codice quando è contrassegnata dal unsafemodificatore. Ilunsafe code oppure il codice non gestito è un blocco di codice che utilizza un file pointer variabile.

Note- Per eseguire i programmi menzionati in questo capitolo su codingground , impostare l'opzione di compilazione in Progetto >> Opzioni di compilazione >> Comando di compilazione su

mcs *.cs -out:main.exe -unsafe"

Puntatori

UN pointerè una variabile il cui valore è l'indirizzo di un'altra variabile, cioè l'indirizzo diretto della posizione di memoria. simile a qualsiasi variabile o costante, è necessario dichiarare un puntatore prima di poterlo utilizzare per memorizzare qualsiasi indirizzo di variabile.

La forma generale di una dichiarazione di puntatore è:

type *var-name;

Di seguito sono riportate dichiarazioni di puntatore valide:

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

L'esempio seguente illustra l'uso dei puntatori in C #, usando il modificatore unsafe -

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();
      }
   }
}

Quando il codice precedente è stato compilato ed eseguito, produce il seguente risultato:

Data is: 20
Address is: 99215364

Invece di dichiarare un intero metodo come non sicuro, puoi anche dichiarare una parte del codice come non sicura. L'esempio nella sezione seguente lo mostra.

Recupero del valore dei dati utilizzando un puntatore

È possibile recuperare i dati memorizzati nella posizione a cui fa riferimento la variabile pointer, utilizzando il ToString()metodo. Il seguente esempio lo dimostra:

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();
      }
   }
}

Quando il codice precedente è stato compilato ed eseguito, produce il seguente risultato:

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

Passaggio di puntatori come parametri ai metodi

È possibile passare una variabile puntatore a un metodo come parametro. Il seguente esempio lo illustra:

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();
      }
   }
}

Quando il codice precedente viene compilato ed eseguito, produce il seguente risultato:

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

Accesso agli elementi della matrice utilizzando un puntatore

In C #, un nome di matrice e un puntatore a un tipo di dati uguale ai dati di matrice non sono lo stesso tipo di variabile. Ad esempio, int * p e int [] p non sono dello stesso tipo. È possibile incrementare la variabile puntatore p perché non è fissata in memoria ma un indirizzo di matrice è fisso in memoria e non è possibile incrementarlo.

Pertanto, se è necessario accedere ai dati di un array utilizzando una variabile del puntatore, come si fa tradizionalmente in C o C ++ (controllare: Puntatori C ), è necessario correggere il puntatore utilizzando ilfixed parola chiave.

Il seguente esempio lo dimostra:

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();
      }
   }
}

Quando il codice precedente è stato compilato ed eseguito, produce il seguente risultato:

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

Compilazione di codice non sicuro

Per compilare codice non sicuro, è necessario specificare il file /unsafe switch della riga di comando con compilatore della riga di comando.

Ad esempio, per compilare un programma denominato prog1.cs contenente codice non sicuro, dalla riga di comando, dare il comando -

csc /unsafe prog1.cs

Se stai usando l'IDE di Visual Studio, devi abilitare l'uso di codice non sicuro nelle proprietà del progetto.

Per fare questo -

  • Aperto project properties facendo doppio clic sul nodo delle proprietà in Esplora soluzioni.

  • Clicca sul Build tab.

  • Seleziona l'opzione "Allow unsafe code".