![]() |
Re: untypisierter pointer
Moin!
Ich verstehe nicht wie du auf die Idee kommst, das WorkArray[0] Nil werden sollte? FreeAndNil() setzt die Variable Temp auf Nil, aber Temp ist doch eine andere Variable und Speicherplatz als WorkArae[0]. Und WorkArea[0] enthält immernoch die alte Adresse genauso wie listview1.selected.data -- diese beiden Stellen hast du auch nie auf Nil gesetzt und daher enthalten die auch noch die alten Adressen und daher kommt es auch beim Zugriff zu einer AV an einer Adresse die nicht gerade neben 000000h liegt... Also: wie kommst du auf die Idee, das WorkArea[0] Nil sein sollte?? MfG Muetze1 |
Re: untypisierter pointer
Hallo Muetze1,
sorry, dass ich so spät antworte, aber die meldungen von DP auf Antworten landen immer im Spamverdacht, warum auch immer... Also zu deinen Fragen: In delphi sind doch meines Wissens nach Variabeln auch nichts anderes als Zeiger auf einen Speicherinhalt. Und ist es nicht auch so, dass wenn ich zwei Objekte a und b habe, dass dann
Delphi-Quellcode:
auch b nil setzt? weil doch bei
a:=b;
a:=nil;
Delphi-Quellcode:
lediglich eine Referenz auf b an a übergibt, oder irre ich da?
a:=b
Und nach dem Prinzip dachte ich würde auch das funktionieren:
Delphi-Quellcode:
Data ist ein Zeiger, und jetzt wird die Speicheradresse meines Objekts an Temp übergeben. Durch freeandnil wird der Speicherbereich meines Objekts freigegeben. und demnach sollte dann auch
temp:=tstringlist(listview1.selected.data);
freeandnil(temp);
Delphi-Quellcode:
true liefern und keine AV.
workarray[0]=nil
Wo genau ist da jetzt mein Fehler? Gruß Jan |
Re: untypisierter pointer
Moin!
Zitat:
Delphi-Quellcode:
und somit ein Zeiger auf ein Byte. Bei irgendwelchen Variablen die Objekte sind, sind es automatisch Zeiger.
Type PByte = ^Byte;
Zitat:
Beispiel:
Delphi-Quellcode:
program TestReference;
{$APPTYPE CONSOLE} uses sysutils; Var a, b : TObject; begin WriteLn('Objekte - Zuweisungsspiele'); a := Nil; b := Nil; WriteLn('a = 0x', IntToHex(Integer(a), 8), ' b = 0x', IntToHex(Integer(b), 8)); a := TObject.Create; WriteLn('a = 0x', IntToHex(Integer(a), 8), ' b = 0x', IntToHex(Integer(b), 8)); b := a; WriteLn('a = 0x', IntToHex(Integer(a), 8), ' b = 0x', IntToHex(Integer(b), 8)); FreeAndNil(a); WriteLn('a = 0x', IntToHex(Integer(a), 8), ' b = 0x', IntToHex(Integer(b), 8)); ReadLn; end. Zitat:
Zitat:
Wenn da immer Referenzen übergeben werden würden, dann müsste man ja mehr als höllisch aufpassen - wenn du dir irgendwo eine Zahl veränderst, an wieviel anderen Stellen auf einmal auch eine andere Zahl drinne steht. MfG Muetze1 |
Re: untypisierter pointer
Hallo Muetze1,
erstmal vielen Dank für deine ausführliche und geduldige Antwort auf mein Problem, das ist nämlich wirklich der einzige verbleibende Bug bevor ich das Programm endlich posten kann. Also soweit verstehe ich was du sagen willst, durch das freeandnil wird nicht das objekt gelöscht, auf das die variable zeigt, sondern die im Speicher abgelegt Adresse zu meinem Objekt, so dass meine Variable nichtmehr auf mein Objekt zeigt. Nur ist aber meine Frage: warum klappt folgendes nicht:
Delphi-Quellcode:
Ohne freeandnil gibt showmessage den gewünschten string an, aber mit freeandnil bekomme ich eine AV, weil wohl anscheinend die Stringlist auf die ich zugreife nichtmehr existiert.
temp:=tstringlist(listview1.selected.data);
freeandnil(temp); showmessage(workarray[0].strings[0]); Das ist ja eigentlich genau was ich will, aber trotzdem klappt die Abfrage ob workarray[0] nil ist nicht. Ich habe hier massive Verständnisschwierigkeiten. Gruß Jan |
Re: untypisierter pointer
Kann mir denn dabei wirklich keiner Helfen?
Müsste doch für die vielen erfahrenen Programmierer hier kein Problem sein, oder? Gruß Jan |
Re: untypisierter pointer
Moin!
Zitat:
Zitat:
Zitat:
Du hast in dem Code 4 Stellen im Speicher: 1. Stelle: Das ist ein grösserer Block der die Instanz von der TStringList enthält 2. Stelle: Das ist die Data Eigenschaft eines TListItems der TListView (also die Data Eigenschaft eines Elements der TListView). Diese Stelle im Speicher enthält nicht das Objekt sondern nur die Adresse wo 1. liegt (ein Pointer) 3. Stelle: Das ist ein Eintrag in dem Array WorkArray[] welches einfach auch nur die Adresse des Objektes (welches hier 1. ist) enthält. Also auch hier nur ein Zeiger auf die 1. Stelle - kein Objekt selber. 4. Stelle: der Platz im Speicher für die Variable Temp. Auch ein Zeiger - ein Zeiger der auf nix zeigt. So und nun nochmal dazu, was dein Code macht: Zeile a): Der Inhalt des Zeigers aus 2. (also nur die Adresse wo 1. im Speicher liegt) wird kopiert und in 4. abgelegt. 4. ist auch nur ein Zeiger und zeigt danach auf die selbe Stelle im Speicher wie 2. Zeile b): Das Objekt was an Stelle 1 liegt wird freigegeben - der Speicher bei der 1. Stelle wird also freigegeben und wird vom Programm für anderes genutzt. Danach wird durch FreeAndNil() in Stelle 4 noch eine 0 eingetragen, so dass Stelle 4 nicht mehr weiss wo der Speicherblock aus 1. geblieben ist. Stelle 2 und Stelle 3 aber hat keiner was gesagt, daher zeigen diese immernoch auf die gleiche Stelle im Speicher - da wo 1. mal lag, aber nun ja nicht mehr. Zeile c): Du greifst auf die 3. Stelle im Speicher zu, welche ja immernoch wie die 2. Stelle im Speicher noch die alte Position von 1. beinhalteten. Dort greift nun auch ShowMessage zu um sich von dort den String zu holen (aus dem Speicherbereich bei 1.), aber da ist ja nix mehr, daher greift er ins Leere und es gibt eine AV. So langsam weiss ich nicht mehr wie ich das technisch erklären soll. Falls es immernoch hapert, dann hier nochmal eine "nicht-technische Erklärung": Folgende Situation: Du hast ein Geheimversteck mit 2 Freunden. Dieses kennt ihr alle 3 und jeder kann da mal was hinpacken und die anderen können es sich dann anschauen. Daher folgende Situation: Wir haben ein Versteck V und 2 Freunde (Freund1, Freund2) und natürlich dich (Jan). Situation am Anfang: Freund1 kennt V Freund2 kennt V Jan kennt V Sagen wir mal du musstest letztens feststellen das jemand anders das Versteck gefunden hatte und somit ist es nicht mehr sicher, geschweige denn geheim. Nun nimmst du die dort von euch abgelegte Dinge erstmal in Verwahrung und suchst ein neues Versteck. Als du eins gefunden hast, musst du ja nun noch deinen beiden Freunden bescheid geben wo sich dies neue Versteck befinden - du selber weisst es ja, du hast es ja gefunden. Nun ist aber das Problem, das dein Handy alle ist und du somit Freund1 und Freund2 nicht über das neue Geheimversteck (nennen wir es mal N) informieren kannst. Daher haben wir danach folgende Situation: Freund1: kennt nur V - also das alte Versteck (welches nicht mehr existiert) Freund2: kennt auch nur V - also auch nur das alte Versteck (welches nicht mehr existiert) Jan: du kennst das neue Versteck N Problem: Wenn du das nächste mal einen von beiden triffst und ihnen nicht erzählst wo das neue Versteck N sich befindet und du ihnen z.B: nur sagst das du die Lösungen für die neue Mathearbeit im Geheimversteck hinterlegt hast, dann schauen Freund1 und Freund2 beim alten Versteck V nach, aber da ist nix mehr - daher schreiben sie nächsten Tag eine schlechte Arbeit und sind böse auf dich (-> Exception :wink: ). Ende... Grundlegend: jeder (du und deine Freunde) können sich für sich selber die Position des Versteckes merken. Wenn du ihnen die neue Position nicht mitteilst, haben sie immernoch die alte Position im Kopf. Gleiches gilt für die Variablen die sich die Position des Objektes merken (Temp, WorkArray[0], ListView1.Selected.Data): wenn du nicht allen Bescheid sagst, wissen manche nix von der Veränderung - sie merken sich das auch alle für sich. Ich hoffe das dies hilft den Groschen weiter rutschen zu lassen... :mrgreen: MfG Muetze1 PS: Die Story hat (c) - ich rede gerade mit einem Verleger über ein Zeiger-Kinderbuch... *g* |
Re: untypisierter pointer
Wow!
Also deine Bemühungen sind echt bemerkenswert, so eine Antwort hab ich noch nie bekommen. Aber, ohne dich jetzt enttäuschen zu wollen, es hätte wirklich gereicht mir zu sagen, dass freeandnil sowohl den Speicherbereich für die Variable, als auch den Speicherbereich für das Objekt, auf welches die Variable zeigt löscht, oder irgendwie auf was anderes setzt. Das wusste ich nämlich nicht. Jetzt ist mir auch klar, warum die Abfrage auf nil beim array[0] nicht funktioniert. Aber eine ganz klasse Antwort hast du geschrieben. Danke! Gut.. jetzt weiss ich warum das ganze nicht klappt, aber was kann ich dagegen machen? wie prüfe ich jetzt, ob workarray[0] noch auf ein gültiges TStringlist Objekt im Speicher zeigt, oder nicht? einfach ausprobieren und dann exception abfangen? Ich habe versucht die Variable zu dereferenzieren und dann auf nil abzufragen, aber das mag Delphi verständlicher Weise nicht. Und da weiß ich dann auch schon nichtmehr weiter. Gruß Jan |
Re: untypisierter pointer
Moin Jan,
Zitat:
Es wird das Objekt freigegeben, auf das der Pointer, den die Variable enthält, zeigt. Der Inhalt der Variablen wird auf nil gesetzt. Der Speicherbereich für die Variable selbst bleibt davon unberührt. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:20 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz