Unsicherer C#-Code meistern: Zeiger und Speicherverwaltung
Unsicherer Code und Zeiger in C#
C# erlaubt die Verwendung von Zeigervariablen in einer Funktion oder einem Codeblock, wenn dieser mit dem unsafe-Modifizierer gekennzeichnet ist. Unsicherer Code (oder unverwalteter Code) ist ein Codeblock, der eine Zeiger-Variable verwendet.
Zeiger
Ein Zeiger ist eine Variable, deren Wert die Adresse einer anderen Variablen ist – also die direkte Adresse der Speicherposition. Ähnlich wie bei jeder Variablen oder Konstanten müssen Sie einen Zeiger deklarieren, bevor Sie ihn zum Speichern einer Variablenadresse verwenden können.
Die allgemeine Form einer Zeigerdeklaration lautet:
type *var-name;
Gültige Zeigerdeklarationen sind beispielsweise:
int *ip; // Zeiger auf eine Ganzzahl double *dp; // Zeiger auf einen Double float *fp; // Zeiger auf einen Float char *ch; // Zeiger auf einen 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 wird, erzeugt er folgendes Ergebnis (die Adresse variiert):
Data is: 20 Address is: 99215364
Statt eine gesamte Methode als unsafe zu deklarieren, können Sie auch nur einen Teil des Codes als unsafe kennzeichnen. Der folgende Abschnitt zeigt dies.
Datenwert über einen Zeiger abrufen
Sie können den an der vom Zeiger referenzierten Speicherposition gespeicherten Datenwert mithilfe der ToString()-Methode abrufen. 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 wird, erzeugt er folgendes Ergebnis:
Data is: 20 Data is: 20 Address is: 77128984
Zeiger als Parameter an Methoden übergeben
Sie können eine Zeigervariable als Parameter an eine Methode ü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 folgendes Ergebnis:
Before Swap: var1: 10, var2: 20 After Swap: var1: 20, var2: 10
Array-Elemente über einen Zeiger zugreifen
In C# sind ein Array-Name und ein Zeiger auf einen Datentyp, der dem Array-Datentyp entspricht, nicht dieselbe Variablentyp. Zum Beispiel sind int *p und int[] p nicht derselbe Typ. Sie können die Zeigervariable p inkrementieren, da sie nicht im Speicher fixiert ist, aber eine Array-Adresse ist im Speicher fixiert und kann nicht inkrementiert werden.
Daher müssen Sie, wenn Sie über eine Zeigervariable auf Array-Daten zugreifen möchten (wie es traditionell in C oder C++ üblich ist), den Zeiger mithilfe des fixed-Schlüsselworts 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) // Array-Adresse im Zeiger
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 wird, erzeugt er folgendes 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
Kompilieren von unsicherem Code
Für die Kompilierung von unsicherem Code müssen Sie den /unsafe-Befehlszeilenschalter beim Kommandozeilen-Compiler angeben.
Beispiel: Um ein Programm namens prog1.cs mit unsicherem Code über die Kommandozeile zu kompilieren, geben Sie den Befehl ein:
csc /unsafe prog1.cs
Wenn Sie die Visual Studio IDE verwenden, müssen Sie die Verwendung von unsicherem Code in den Projekteigenschaften aktivieren:
Öffnen Sie die Projekteigenschaften, indem Sie im Solution Explorer doppelt auf den Eigenschaften-Knoten klicken.
Klicken Sie auf die Registerkarte Build.
Aktivieren Sie die Option "Allow unsafe code".
C Sprache
- Widerstand-Farbcodes – Umfassender Leitfaden zum Dekodieren von Wert, Toleranz und E-Reihen-Standards
- Standard-Verdrahtungs-Farbcodes für AC- & DC-Schaltungen – IEC, USA, UK & Kanada
- C++ Zeiger meistern: Konzepte, Beispiele & praktische Anwendungen
- Zeiger in C: Umfassender Leitfaden zu Typen, Verwendung und Best Practices
- C-Zeiger meistern: Praktische Schritte zur fortgeschrittenen Programmierung
- Data Matrix vs. QR Codes: Welcher ist am besten für Ihr Business?
- Vollständiger Leitfaden zu Haas Fräsen M-Codes: Funktionen, Einstellungen & Anwendung
- Umfassender Leitfaden zu Mach3 M-Codes für CNC-Bearbeitung
- M-Code-Meisterschaft: CNC-Programmierquiz
- G-Codes meistern: CNC-Programmierquiz