Adressen von Variablen oder Funktionsblöcken werden in Zeigern gespeichert, während ein Programm läuft⮫ Adressen.
Zeigerdeklarationen haben die folgende Syntax:
<Identifier>: POINTER TO <Datatype/Functionblock>;
Ein Zeiger kann auf jeden Datentyp oder Funktionsblock zeigen, sogar auf benutzerdefinierte Typen.
Die Funktion des Adressoperators ADR besteht darin, dem Zeiger die Adresse einer Variablen oder eines Funktionsblocks zuzuweisen.
Ein Zeiger kann dereferenziert werden, indem der Inhaltsoperator "^" nach dem Zeigerbezeichner hinzugefügt wird.
Ein Zeiger wird byteweise hochgezählt ! Man kann sie wie im C-Compiler üblich hochzählen lassen, indem man die Anweisung p=p+SIZEOF(p^); verwendet.
Beispiel:
pt:POINTER TO INT; var_int1:INT := 5; var_int2:INT; pt := ADR(var_int1); var_int2:= pt^; (* var_int2 is now 5 *)
Überprüfung von Zeigerzugriffen während der Laufzeit
Zur Überprüfung von Zeigerzugriffen während der Laufzeit können Sie Prüffunktionen erstellen, die automatisch vor jedem Zugriff auf die Adresse eines Zeigers aufgerufen werden. Dazu muss die entsprechende Funktion im Projekt direkt oder über eine Bibliothek verfügbar sein. Die folgenden Funktionen werden unterstützt:
-
Funktion CheckPointer: prüft, ob die aktuell am Pointer gespeicherte Adresse innerhalb des gültigen Speicherbereichs liegt,
-
Funktion CheckPointerAligned: impliziert die Funktionalität von CheckPointer und überprüft zusätzlich die Speicherausrichtung.
Die Funktionen müssen genau die genannten Namen haben. Sie geben die Adresse zurück, die für die Dereferenzierung des Zeigers verwendet wird, also bestenfalls diejenige, die als erster Eingabeparameter übergeben wurde (dwAddress im untenstehenden Beispiel).
Sehen Sie im folgenden Beispiel einer CheckPointerAligned-Funktion, welche Eingabeparameter verarbeitet werden. Auch die Parameternamen sind Beispiele. Eine CheckPointer-Funktion muss genauso aussehen, nur dass es keinen Parameter für die Granularität des Zeigerzugriffs geben darf:
|
(* Der Datentyp der Funktion (Rückgabewert) muss derselbe sein, der für Zeiger im aktuell eingestellten Zielsystem verwendet wird, d.h. DWORD für Systeme mit 32-Bit-Zeigern, WORD für Systeme mit 16-Bit-Zeigern *) |
|
|
|
(* Zieladresse des Zeigers; der Datentyp muss derselbe sein, der für Zeiger im aktuell eingestellten Zielsystem verwendet wird, siehe oben: Rückgabewert *) |
|
(* Größe des Zeigerzugriffs; der Datentyp muss ganzzahlkompatibel sein und die maximal mögliche Datengröße abdecken, die an der Zeigeradresse gespeichert ist *) |
|
(* ! nicht in CheckPointer-Funktionen zu verwenden ! : Granularität des Zugriffs, z. B. "2", wenn INT der kleinste nicht strukturierte Datentyp ist, der an der angegebenen Adresse verwendet wird; der Datentyp muss ganzzahlkompatibel sein *) |
|
(*Zugangsart: Lesen oder Schreiben; TRUE=Lesezugriff; der Datentyp muss BOOL sein *) |
|
|
Wenn eine CheckPointer-Funktion und eine CheckPointerAligned-Funktion im Projekt vorhanden sind, wird CheckPointerAligned aufgerufen.