C# Language
Osäker kod i .NET
Sök…
Anmärkningar
- För att kunna använda det
unsafe
nyckelordet i ett .Net-projekt måste du markera "Tillåt osäker kod" i Projektegenskaper => Bygg - Att använda osäkra koder kan förbättra prestandan, men det är på bekostnad av kodesäkerhet (därmed termen
unsafe
).
Till exempel, när du använder en för loop, en matris som så:
for (int i = 0; i < array.Length; i++)
{
array[i] = 0;
}
.NET Framework säkerställer att du inte överskrider gränserna för matrisen och kastar ett IndexOutOfRangeException
om indexet överskrider gränserna.
Om du använder osäker kod kan du dock överskrida matrisens gränser så:
unsafe
{
fixed (int* ptr = array)
{
for (int i = 0; i <= array.Length; i++)
{
*(ptr+i) = 0;
}
}
}
Osäker arrayindex
void Main()
{
unsafe
{
int[] a = {1, 2, 3};
fixed(int* b = a)
{
Console.WriteLine(b[4]);
}
}
}
Att köra den här koden skapar en matris med längd 3, men försöker sedan få det femte objektet (index 4). På min maskin skrivs detta ut 1910457872
, men beteendet definieras inte.
Utan det unsafe
blocket kan du inte använda pekare och kan därför inte komma åt värden förbi slutet av en matris utan att orsaka att ett undantag kastas.
Använda osäkra med matriser
Vid åtkomst till matriser med pekare finns det ingen gränskontroll och därför kommer ingen IndexOutOfRangeException
att kastas. Detta gör koden snabbare.
Tilldela värden till en matris med en pekare:
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
}
}
}
}
}
Medan den säkra och normala motsvarigheten skulle vara:
class Program
{
static void Main(string[] args)
{
int[] array = new int[1000];
for (int i = 0; i < array.Length; i++)
{
array[i] = i;
}
}
}
Den osäkra delen kommer i allmänhet att vara snabbare och skillnaden i prestanda kan variera beroende på komplexiteten hos elementen i matrisen såväl som den logik som tillämpas på var och en. Även om det kan vara snabbare, bör det användas med försiktighet eftersom det är svårare att underhålla och lättare att bryta.
Använda osäkra med strängar
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"