C# Language
Codice non sicuro in .NET
Ricerca…
Osservazioni
- Per poter utilizzare la parola chiave
unsafe
in un progetto .Net, è necessario selezionare "Consenti codice non sicuro" in Proprietà progetto => Build - L'utilizzo di codice non sicuro può migliorare le prestazioni, tuttavia, è a scapito della sicurezza del codice (quindi il termine
unsafe
).
Ad esempio, quando usi un ciclo for un array in questo modo:
for (int i = 0; i < array.Length; i++)
{
array[i] = 0;
}
.NET Framework garantisce che non si superi i limiti dell'array, lanciando una IndexOutOfRangeException
se l'indice supera i limiti.
Tuttavia, se si utilizza un codice non sicuro, è possibile superare i limiti dell'array in questo modo:
unsafe
{
fixed (int* ptr = array)
{
for (int i = 0; i <= array.Length; i++)
{
*(ptr+i) = 0;
}
}
}
Indice di matrice non sicuro
void Main()
{
unsafe
{
int[] a = {1, 2, 3};
fixed(int* b = a)
{
Console.WriteLine(b[4]);
}
}
}
L'esecuzione di questo codice crea una matrice di lunghezza 3, ma poi tenta di ottenere il quinto elemento (indice 4). Sulla mia macchina, questo stampato 1910457872
, ma il comportamento non è definito.
Senza il blocco unsafe
, non è possibile utilizzare i puntatori e, pertanto, non è possibile accedere ai valori oltre la fine di un array senza che venga generata un'eccezione.
Utilizzo non sicuro con gli array
Quando si accede agli array con puntatori, non vi è alcun controllo sui limiti e pertanto non verrà generata IndexOutOfRangeException
. Questo rende il codice più veloce.
Assegnazione di valori a un array con un puntatore:
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
}
}
}
}
}
Mentre la controparte sicura e normale sarebbe:
class Program
{
static void Main(string[] args)
{
int[] array = new int[1000];
for (int i = 0; i < array.Length; i++)
{
array[i] = i;
}
}
}
La parte non sicura sarà generalmente più veloce e la differenza di prestazioni può variare in base alla complessità degli elementi nell'array e alla logica applicata a ciascuno. Anche se potrebbe essere più veloce, dovrebbe essere usato con cautela poiché è più difficile da mantenere e più facile da rompere.
Usando non sicuro con le stringhe
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"