C# Language
Onveilige code in .NET
Zoeken…
Opmerkingen
- Om het
unsafe
trefwoord in een .Net-project te kunnen gebruiken, moet u "Onveilige code toestaan" aanvinken in Projecteigenschappen => Build - Het gebruik van onveilige code kan de prestaties verbeteren, maar dit gaat ten koste van codeveiligheid (vandaar de term
unsafe
).
Als u bijvoorbeeld een for-lus gebruikt, is een array als volgt:
for (int i = 0; i < array.Length; i++)
{
array[i] = 0;
}
.NET Framework zorgt ervoor dat u de grenzen van de array niet overschrijdt, waardoor een IndexOutOfRangeException
als de index de grenzen overschrijdt.
Als u echter onveilige code gebruikt, kunt u de grenzen van de array als volgt overschrijden:
unsafe
{
fixed (int* ptr = array)
{
for (int i = 0; i <= array.Length; i++)
{
*(ptr+i) = 0;
}
}
}
Onveilige array-index
void Main()
{
unsafe
{
int[] a = {1, 2, 3};
fixed(int* b = a)
{
Console.WriteLine(b[4]);
}
}
}
Het uitvoeren van deze code maakt een array met lengte 3, maar probeert vervolgens het 5e item te krijgen (index 4). Op mijn machine is dit 1910457872
afgedrukt, maar het gedrag is niet gedefinieerd.
Zonder het unsafe
blok kunt u geen verwijzingen gebruiken en hebt u dus geen toegang tot waarden voorbij het einde van een array zonder dat er een uitzondering wordt gegenereerd.
Onveilig gebruiken met arrays
Bij toegang tot arrays met pointers zijn er geen IndexOutOfRangeException
en daarom wordt er geen IndexOutOfRangeException
gegenereerd. Dit maakt de code sneller.
Waarden toewijzen aan een array met een aanwijzer:
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
}
}
}
}
}
Terwijl de veilige en normale tegenpartij zou zijn:
class Program
{
static void Main(string[] args)
{
int[] array = new int[1000];
for (int i = 0; i < array.Length; i++)
{
array[i] = i;
}
}
}
Het onveilige deel is over het algemeen sneller en het verschil in prestaties kan variëren, afhankelijk van de complexiteit van de elementen in de array en de logica die op elk element wordt toegepast. Hoewel het sneller kan zijn, moet het voorzichtig worden gebruikt, omdat het moeilijker te onderhouden en gemakkelijker te breken is.
Onveilig gebruiken met tekenreeksen
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"