Zitat von
Jürgen Thomas:
Für diese Prüfung ist Folgendes vorgesehen (ich weiß aber nicht, ob damit alle denkbaren Probleme abgehandelt werden):
Delphi-Quellcode:
if assigned(StringList1)
begin
// ...
end;
Nein! Das ist hier völlig falsch. Assigned prüft nur ob eine Variable eine gültige Referenz darstellt. Dazu wird ein Zeiger auf die Ungleichheit mit nil geprüft. Da es ziemlich genau 2^32 Adressen (auf einem 32 Bit System) gibt, die möglich sind und davon genau eine nil ist, sind die Chancen also gut hier ein assigned(X) = True zu bekommen.
Gerade bei lokalen Variablen ist das ein Problem, diese werden nämlich nicht initialisiert (gibt aber auch ein Warning und steht in der
OH).
Delphi-Quellcode:
procedure doFoo;
var x : ^Integer;
begin
// hm, ist x assigned?
// hier wurde noch keine gültige Adresse zugewiesen,
// trotzdem kann in jedem Durchlauf diese Bedingung wahr werden
// da die Werte lokaler Adressen zufällig sind, weiß man nie was drin steht
// bis es zugewiesen wurde
if assigned(x) then
begin
...
end;
new(x);
// ok, jetzt hat x eine gültig Adresse
dispose(x);
// und die bleibt gespeichert, auch wenn der Speicher an dieser
// Adresse schon wieder frei gegeben wurde
if assigned(x) then
begin
// ist wahr!
end;
end;
Dispose und Free kümmern sich, wie _frank_ schon sagte nur um das freigeben des Speichers. Dies liegt schon allein daran, dass du mehr als einen Zeiger auf den gleichen Adressbereich haben kannst. Bei Klassentypen wäre das natürlich mehr als eine Referenz. Hier gibt nur keine map, in der alle Zeiger auf eine Adresse gespeichert werden (zu der Adresse). Somit kann der Speicher an dieser Adresse frei gegeben werden, aber dein Programm kennt nicht alle Zeiger/Referenzen auf diesen Bereich und setzt diese deswegen auch nicht auf nil. Dass solltest du also explizit im Code machen.
Gruß Der Unwissende