Thema: Delphi Zeigerproblem

Einzelnen Beitrag anzeigen

Muetze1
(Gast)

n/a Beiträge
 
#9

Re: Zeigerproblem

  Alt 4. Apr 2008, 22:29
Zitat von nEmai:
Ok, das heißt, wenn ich es richtig versteh:
Image.Picture.Bitmap ist ein Pointer auf eine Bitmap, also eine Speicheradresse.

Dann müsste
Delphi-Quellcode:
var
  ptrBitmap: ^TBitmap;
begin
  ptrBitmap:= Image.Picture.Bitmap;
end;
ja funktionieren.
Es kommt aber inkompatible Typen Pointer und TBitmap.
Wird das schon intern dereferenziert und wenn ja gibt es einen Befehl mit dem man es verhindern kann?
(Ich wüsste einfach gern ob und wie ich darauf einen eigenen Pointer machen kann.)

MfG^^
Jain. Mal ein wenig ausführlicher:

Wir nehmen uns ein Objekt:

Delphi-Quellcode:
var
  a: TObject;
Dann hast du dort an der Stelle von a nicht direkt das komplette TObject mit allen seinen Methoden und Feldern sondern nur einen Zeiger. Dieser würde dann auf den Speicherbereich zeigen, wo die Felder, etc liegen. Wenn du diese Variable deklariert hast, kannst du ja mal mit SizeOf(a) deren Grösse ermitteln: du wirst 4 bekommen. 4 Bytes, also genau die Grösse eines Pointers.

Du musst, um das Objekt nutzen zu können, die eine Instanz erstellen. Diese erhälst du mit dem Konstruktor-Aufruf. Dieser reserviert den notwendigen Speicher für das Objekt und gibt dir den Zeiger genau auf diesen Speicherbereich zurück. Von daher kannst du es auch abfragen ob ein Objekt existiert, wenn die Variable ordentlich intialisiert wird. Du kannst mit einem Vergleich auf <> nil abprüfen, ob schon eine Adresse drinne steht (wie bei einem Pointer btw).

Deshalb haben auch viele Probleme mit den Objekten, wenn sie Free aufrufen und danach weiterhin auf das Objekt zugreifen und AV's bekommen und selbst Assigned() bzw. ein Vergleich auf Nil nichts bringt: Der Zeiger zeigt weiterhin auf die Adresse (hat ihm ja keiner was anderes gesagt), aber da ist nichts mehr. Somit: FreeAndNil() ruft Free auf und setzt den Zeiger auf NIL und somit klappen die Abfragen auch.

Anderes Beispiel:

Delphi-Quellcode:
var
  a, b: TStrings;
begin
  a := TStringList.Create; // neue Instanz
  b := a; // Objekt wird nicht kopiert, nur der Zeiger!

  a.Text := 'erstes Object';

  ShowMessage(b.Text);
end;
Bei dem Beispiel erzeugst du nur ein Objekt. Wäre a und b jeweils intern kein Zeiger, dann müsste er das komplette Objekt kopieren, da es komplett eigene Speicherbereiche sind. Wenn dem so ist, dann müsste die ShowMessage() einen leeren String ausgeben. Tut er aber nicht, sondern er gibt "erstes Object" aus. Grund dafür: er kopiert nur die Adresse aus dem Pointer in den anderen. Somit zeigen beide auf das selbe Objekt im Speicher.

Also: Wenn du eine Objektvariable deklarierst, ist diese nur 4 Bytes gross, da es ein Zeiger ist.

Dies ist das interne Handling, somit geschieht auch die Dereferenzierung automatisch intern von Delphi. Und ausserdem ist Delphi recht typensicher (wie oft habe ich das in den letzten Tagen geschrieben...) und TBitmap und Pointer sind nunmal unterschiedliche Typen.
  Mit Zitat antworten Zitat