Unsicherer Code via unsafe Zeiger in C – Teil 2 (Teil 2)
Kommentare

Auslesen von Speicheradressen
Innerhalb eines unsafe-Blocks können auf einfache Art und Weise die Speicheradressen von Variablen ermittelt werden. Zu Beginn von Listing 3 werden drei Wertevariablen

Auslesen von Speicheradressen

Innerhalb eines unsafe-Blocks können auf einfache Art und Weise die Speicheradressen von Variablen ermittelt werden. Zu Beginn von Listing 3 werden drei Wertevariablen vom Typ int, byte und double angelegt. Anschließend werden die Speichergröße, der Inhalt und die Speicheradresse einer jeden Variablen auf der Konsole ausgegeben. Die Ermittlung der Speicheradresse geschieht mithilfe des &-Operators. Die Ermittlung einer Speicheradresse eines Referenztyps, wie z. B. eines String-Typs, ist allerdings nicht so einfach möglich.

Listing 3

public static void AddressOf()
{
  int intZahl = 112;
  byte byteZahl = 42;
  double dblZahl = 9.51;
  unsafe
  {
    Console.WriteLine("Speicheradresse von intZahl ist 0x{0:X} | Größe: {1} - 
        Inhalt: {2}", (uint)&intZahl, sizeof(int), intZahl);
    Console.WriteLine("Speicheradresse von byteZahl ist 0x{0:X} | Größe: {1} - 
        Inhalt: {2}", (uint)&byteZahl, sizeof(byte), byteZahl);
    Console.WriteLine("Speicheradresse von dblZahl ist 0x{0:X} | Größe: {1} - 
        Inhalt: {2}", (uint)&dblZahl, sizeof(double), dblZahl);
  }        
}  

Quicksort mit Zeigern

Als erweitertes Beispiel wird als Nächstes der bekannte Quicksort-Algorithmus , basierend auf Zeigern, umgesetzt. Listing 4 zeigt die vollständige Implementierung.

Listing 4: Quicksort

public static unsafe void QuickSortPointer(int* max, int* min)
{
  if (min < max)
  {
    long toProcess = max - min;
    int middle = *(min + (toProcess / 2));
    int* saveMin = min;
    int* saveMax = max;
    while (min <= max)
    {
      while ((min < saveMax) && (*min < middle)) ++min;
      while ((max > saveMin) && (*max > middle)) --max;
      if (min < max)
      {
        temp = *min;
        *min = *max;
        *max = temp
   }
      if (min <= max)
      {
        ++min;
        --max;
      }
    }
    if (min < saveMax)
      QuickSortPointer (saveMax, min);
    if (max > saveMin)
      QuickSortPointer (max, saveMin);
  }
}
public static int[] QuickSort(int[] unsortNumbers)
{      
  unsafe
  {
    fixed (int* input = unsortNumbers)
    {
      QuickSortPointer (&input[unsortNumbers.Length - 1], input);
    }
  }
  return unsortNumbers;
}  

Startpunkt des Sortiervorgangs ist die Methode QuickSort. Sie erwartet als einzigen Parameter ein Array mit Zahlen. Innerhalb der Methode wird der Zeiger auf das Array mittels fixed fixiert und der eigentlichen Sortiermethode QuickSortPointer übergeben. Die umgesetzte Sortiermethode nutzt nun verschiedene Zeigeroperationen. Der Methode werden zwei Parameter übergeben, die den Bereich des Arrays markieren. Die erste IF-Abfrage prüft, ob sich die Methode innerhalb eines gültigen Bereichs befindet, nur dann wird eine Sortierung ausgeführt. Ist dies der Fall, wird der Mittelpunkt innerhalb des Bereichs bestimmt und in der Variablen middle gespeichert. Der Mittelpunkt wird als Pivot-Element verwendet. Danach wird zunächst im linken Bereich ein Element gesucht, das kleiner ist als der bestimmte Pivot-Wert. Anschließend wird im rechten Bereich ein Wert gesucht, der größer ist als der Pivot-Wert. Die zwei gefundenen Elemente werden anschließend nur getauscht, wenn der Wert aus dem linken Bereich kleiner ist als der aus dem rechten Bereich. Am Ende der Methode ruft sich die Methode rekursiv selbst auf, wenn noch unsortierte Bereiche existieren.

Unsere Redaktion empfiehlt:

Relevante Beiträge

Meinungen zu diesem Beitrag

X
- Gib Deinen Standort ein -
- or -