Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi untypisierter pointer (https://www.delphipraxis.net/35254-untypisierter-pointer.html)

Jan 4. Dez 2004 14:19


untypisierter pointer
 
Hallo DPler,
ich habe in meinem Programm ein TListview, dessen untereigenschaft tlistitem die Eigenschaft "Data" hat, welches ein untypisierter Zeiger auf ein Beliebiges Objekt ist. Über diese Eigenschaft habe ich jetzt die einzelnen Einträge meines Datenarrays verlinkt, (Array of Tstringlist) habe jetzt also einen untypisierten pointer auf ein Tstringlist Objekt. Jetzt muss ich zwei Dinge herausfinden:
Wie kann ich das TStringlist Objekt auf nil setzen, und nicht den pointer, ohne dass ich eine Exception bekomme? Und 2.: gibt es eine Möglichkeit über den Zeiger auf das TStringlist Objekt irgendwie eine referenz auf den Array of Tstringlist zu bekommen, welcher das TStringlist Objekt beherbergt?
Danke an alle die sich die Zeit nehmen das hier zu lesen!
Gruß
Jan

paresy 4. Dez 2004 14:56

Re: untypisierter pointer
 
Zitat:

Wie kann ich das TStringlist Objekt auf nil setzen, und nicht den pointer, ohne dass ich eine Exception bekomme?
wenn du das objekt im array auf nil setzt, quasi zerstörst... dann erzeugt delphi beim zugreifen über die data property ne exception weil das objekt nicht mehr verfügbar ist.

du müsstest also auch die data property auf NIL setzten und dann mit assigend(data) abfragen

Zitat:

gibt es eine Möglichkeit über den Zeiger auf das TStringlist Objekt irgendwie eine referenz auf den Array of Tstringlist zu bekommen, welcher das TStringlist Objekt beherbergt?
nicht dass ich wüsste bzw den sinn darin sehen würde



poste mal nen code beispiel... dann ist es immer einfach tipps zu geben.

grüße paresy

fiasko 4. Dez 2004 17:13

Re: untypisierter pointer
 
Hallo,

Zitat:

Zitat von Jan
Und 2.: gibt es eine Möglichkeit über den Zeiger auf das TStringlist Objekt irgendwie eine referenz auf den Array of Tstringlist zu bekommen, welcher das TStringlist Objekt beherbergt?


Delphi-Quellcode:
type
  TMyFunnyArrayType = array of TStringList;
  PMyFunnyArrayPointer = ^TMyFunnyArrayType;

//...

     PMyFunnyArrayPointer(lv.items[1].data)^
//   <------------------------------------->
//  Das ist jetzt vom Typ array of TStringList
Es kommt jetzt darauf an wie du das Objekt in das data geschrieben hast. Wenn dort ein Zeiger auf ein TStringList steht klappt das wie oben, wenn du einfach das Objekt umgecastet und reingeschrieben hast müßte folgendes gehen:


Delphi-Quellcode:
     TMyFunnyArrayType(lv.items[1].data)
//   <------------------------------------->
//  Das ist jetzt vom Typ array of TStringList
Für einfach native Typen (die nur aus einem Schlüsselwort bestehen) kann man sich diese indirektionsstufe mit zusätzlichen Typen auch sparen.

Jan 5. Dez 2004 17:35

Re: untypisierter pointer
 
Hallo Paresy!

Also du hast schon recht, das gibt eine exception, wenn man einen pointer dereferenziert, der auf ein nichtmehr vorhandenes Objekt zeigt.
Aber ich hatte schlicht und einfach die Zuweisung des Pointers "data" falsch gemacht, so dass ein löschen eine exception hervorgerufen hat. Habe das aber durch ausführliches Beschäftigen mit pointern alles begradigen können.
Das mit dem Zeiger auf den Array hat den Sinn, dass ich eine Prozedur habe, welche einen übergebenen array in ein Tlistview schreibt. Nun kann es aber vorkommen, dass der array nur eine auswahl von pointern auf objekte vom typ tstringlist innerhalb eines anderen arrays ist. Und ich will innerhalb dieser prozedur aber herausfinden wie groß der array ist, in dem die objekte und nicht die pointer enthalten sind.

Eine weitere Verwendung ist, dass ich innerhalb des Tlistviews ein tlistitem löschen will. Es soll dann auch das objekt vom typ tstringlist gelöscht werden, auf welches der pointer "Data" von dem tlistitem zeigt. Dieses tstringlist objekt befindet sich in einem array of tstringlist.
nachdem ich das element des arrays gelöscht habe, will ich aber auch die länge des arrays aktualisieren, daher brauche ich einen pointer auf den array.


Hallo fiasko!

Das codesegment was du da verfasst hast wandelt doch einen untypisierten Zeiger "data" in einen zeigre vom typ tstringlist um, oder irre ich?
Wenn aber doch "data" ein Zeiger auf ein objekt vom typen tstringlist ist, was habe ich dann gewonnen? ich will ja einen zeiger auf ein anderes objekt haben (auf das übergeordnete array von dem tstringlist objekt), nicht einen typisierten zeiger auf das selbe objekt.
Kann natürlich auch sein, dass ich unfug rede, aber ich kann das hier nicht ausprobieren, werde das machen, sobald ich zuhause bin.



Danke euch beiden vielmals dass ihr euch damit befasst habt!
Gruß
Jan

fiasko 5. Dez 2004 19:10

Re: untypisierter pointer
 
Hallo,

Zitat:

Zitat von Jan
Das codesegment was du da verfasst hast wandelt doch einen untypisierten Zeiger "data" in einen zeigre vom typ tstringlist um, oder irre ich?

Nein, er macht daraus ein array of TStringList.

Zitat:

Zitat von Jan
ich will ja einen zeiger auf ein anderes objekt haben (auf das übergeordnete array von dem tstringlist objekt), nicht einen typisierten zeiger auf das selbe objekt.

Hmm, was meinst du denn mit übergeordbete array von dem TStringList Objekt :gruebel:? Ich glaub ich hab noch nicht richtig kapiert worauf du deinen Pointer haben möchtest :-) ...

Jan 7. Dez 2004 13:37

Re: untypisierter pointer
 
Hallo Fiasko!
Ich hab einen Array of tstringlist, der eine Filmliste speichert. Die einzelnen tstringlists speichern also jeweils einen Film.
Ich habe jetzt einen Zeiger auf einen dieser Filme, will aber über diesen Zeiger irgendwie an einen Zeiger auf den Array of tstringlist kommen, in dem die Filme gespeichert sind, damit ich dort auslesen kann, wieviele Filme ich in der Filmliste habe.
Gruß
Jan

fiasko 7. Dez 2004 13:41

Re: untypisierter pointer
 
Hallo,

das geht so nicht. Du kannst nicht schauen wo es überall einen Zeiger auf dein Objekt gibt, du mußt dir also selber irgendwo dein array of TStringList speichern.

runger 7. Dez 2004 13:55

Re: untypisierter pointer
 
Hallo,

was bitte schön ist ein untypisierter Zeiger?
Gibts auch typisierte Zeiger?
Der Ausdruck ist schon in sich Quatsch!

Rainer

Muetze1 7. Dez 2004 14:03

Re: untypisierter pointer
 
Moin!

Zitat:

Zitat von runger
Hallo,

was bitte schön ist ein untypisierter Zeiger?
Gibts auch typisierte Zeiger?
Der Ausdruck ist schon in sich Quatsch!

Rainer

Bitte:

Pointer = untypirisierter Zeiger - ein Zeiger auf Daten unbestimmten Typs und daher kann man auch nicht sagen wie gross die Daten sind auf die der Pointer zeigt. Daher kann man auch schlecht mit New() eine Variable des Typs Pointer anlegen lassen - man muss die Grösse angeben.

PChar, PInteger, einfach ein Zeiger auf einen Typen: ^typ = typirisierter Zeiger. Wenn man diesen nutzt weiss der Compiler wie gross die Daten sind auf die der Zeiger zeigt und kann daher u.a. mit einem einfachen New() genügend Speicher reservieren.

Und nun sag mir was daran Quatsch ist und was es daran nicht geben sollte...

MfG
Muetze1

fiasko 7. Dez 2004 14:05

Re: untypisierter pointer
 
Hallo,

Zitat:

Zitat von runger
was bitte schön ist ein untypisierter Zeiger?
Gibts auch typisierte Zeiger?

Ja gibt es. Ein PChar ist ein typisierter Zeiger. Wenn man z.B. typisierte Zeiger inkrementiert/dekrementiert landet man "hinter" dem vorherigen Element, und nicht nur ein Byte weiter. Außerdem muß man sie nicht casten :-)

Zitat:

Zitat von runger
Der Ausdruck ist schon in sich Quatsch!

Heute wohl mit dem falschen Bein aufgestanden?! Der Ausdruck an sich kann nicht quatsch sein, da "typirisert" und "Zeiger" laut Duden nix miteinander zu tuhen haben (:arrow: sich auch nicht widersprechen) :-)

runger 8. Dez 2004 06:32

Re: untypisierter pointer
 
Hallo,

ein Pointer ist nichts anderes als eine Adresse und sonst garnichts!
Einem Pointer kann kein Mensch ansehen was an dieser Speicheradresse, auf die er zeigt steht!

Aus diesem Grund ist der Ausdruck typisierter Pointer absoluter Quatsch!

Rainer

Luckie 8. Dez 2004 06:38

Re: untypisierter pointer
 
Und ein typisierter Pointer beinhaltet für den Compiler noch die Information um was für einen Typ von Daten es sich hinter der Adresse handelt auf die der Zeiger zeigt.

runger 8. Dez 2004 07:57

Re: untypisierter pointer
 
Hallo Luckie,

das möcht ich sehen. Hast du ein Stück Code?
Oder gib mir ein Beispiel für einen "typisierten Pointer"

Rainer

fiasko 8. Dez 2004 08:06

Re: untypisierter pointer
 
Hallo,

Zitat:

Zitat von runger
das möcht ich sehen. Hast du ein Stück Code?
Oder gib mir ein Beispiel für einen "typisierten Pointer"

Ließt du eigentlich die Antworten eigentlich richtig durch :gruebel: Beispiel (grad kein Delphi zur Hand :arrow: Experimental-Code :-):

Delphi-Quellcode:
var
  tpoint: ^Int64;  // Das nennt man einen typisierten,
  utpoint: Pointer; // das einen untypisierten Pointer!

const
  a: array[0..6] of Int64 = (0,1,2,3,4,5,6);

begin
  tpoint = @a;
  utpoint = @a;

  inc(tpoint);
  inc(utpoint);

  // hier sollte tpoint^ den Wert 1 und
  // Int64(utpoint^) den Wert 0 liefern.
end

MrSpock 8. Dez 2004 08:07

Re: untypisierter pointer
 
Hallo runger,

Beispiele für typisierte Zeiger siehst du oben (z.B. im Beitrag von Muetze). Der Compiler prüft deshalb, ob bei einer Zuweisung an diesen Pointer auch der korrekte Typ verwendet wird, d.h. der Pointer zeigt immer auf Strukturen, die ihm vorher in der Definition bekannt gegeben wurde. Über den New Operator kann der Compiler auch feststellen, wieviel Speicherplatz er reservieren muss.

runger 8. Dez 2004 08:58

Re: untypisierter pointer
 
Hallo,

wenn ihr das so seht OK. Vergesst mein Geschwätz!

Danke
Rainer

MrSpock 8. Dez 2004 09:44

Re: untypisierter pointer
 
Irgendwie werde ich den Verdacht nicht los, dass du sauer bist, dass es typisierte Pointer in Pascal gibt. :mrgreen:

Zitat:

Vergesst mein Geschwätz!
... ääh wovon hattest du noch gesprochen?

Jan 13. Dez 2004 17:26

Re: untypisierter pointer
 
Also gerade wenn ein Problem mit diesen unsäglichen Pointern behoben ist kommt das nächste:

Ich habe folgenden code:


Delphi-Quellcode:
      temp:=tstringlist(listview1.selected.data);
      freeandnil(temp);
      if workarray[0]=nil then
        showmessage('bla');
temp ist vom typen tstringlist.
data ist ein pointer auf ein tstringlist element des arrays workarray.
workarray ist ein array vom typen tstringlist.
Wenn ich jetzt zur Laufzeit den ersten Eintrag im Listview löschen will, also den workarray[0] dann soll der zeiger Data vom selektierten Listitem auf temp gespeichert werden, und dann freigegeben werden. Leider klappt aber die Abfrage
Delphi-Quellcode:
if workarray[0]=nil
nicht. Allerding gibt ein Zugriff auf workarray[0] eine AV. Wie kann ich jetzt abfragen ob workarray[0] nun wirklich freigegeben wurde?
Gruß
Jan

Muetze1 13. Dez 2004 18:05

Re: untypisierter pointer
 
Moin!

Die AV kommt doch, weil er schon freigegeben wurde. Du musst nur noch das Array Element 0 löschen...

MfG
Muetze1

Jan 13. Dez 2004 19:22

Re: untypisierter pointer
 
Hallo Muetze1,
natürlich bekomm ich eine AV, muss ja auch, es geht mir aber darum, dass ich bei workarray[0]=nil kein true rausbekomme, obwohl das Element ja freigegeben wurde. Wie kann ich also abfragen ob der workarray[i] freigegeben wurde?
Gruß
Jan

Muetze1 13. Dez 2004 20:46

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

Jan 20. Jan 2005 12:05

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:
a:=b;
a:=nil;
auch b nil setzt? weil doch bei
Delphi-Quellcode:
a:=b
lediglich eine Referenz auf b an a übergibt, oder irre ich da?

Und nach dem Prinzip dachte ich würde auch das funktionieren:

Delphi-Quellcode:
temp:=tstringlist(listview1.selected.data);
      freeandnil(temp);
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
Delphi-Quellcode:
workarray[0]=nil
true liefern und keine AV.
Wo genau ist da jetzt mein Fehler?
Gruß
Jan

Muetze1 20. Jan 2005 14:16

Re: untypisierter pointer
 
Moin!

Zitat:

Zitat von Jan
In delphi sind doch meines Wissens nach Variabeln auch nichts anderes als Zeiger auf einen Speicherinhalt.

Jede Instanzenvariable ist nur ein Zeiger auf das eigentliche Objekt (besser: die eigentliche Objektinstanz). Dieses trifft nicht für eine Variable vom Typ Integer, Record oder sonstiges zu - Ausnahme dabei sind alle die definierten Typen, die bei der Definition ein ^ vor dem Typ tragen. Also z.B. ist ein PByte definiert als
Delphi-Quellcode:
Type PByte = ^Byte;
und somit ein Zeiger auf ein Byte. Bei irgendwelchen Variablen die Objekte sind, sind es automatisch Zeiger.

Zitat:

Zitat von Jan
Und ist es nicht auch so, dass wenn ich zwei Objekte a und b habe, dass dann
Delphi-Quellcode:
a:=b;
a:=nil;
auch b nil setzt?

Nein, warum sollte? Wie oben schon geschrieben sind diese Variablen eigentlich ein Zeiger auf den Speicherbereich wo die Instanz des Objektes liegt - also eigentlich ein normaler Pointer. Daher läuft das so ab, das a auf einen Speicherbereich zeigt und b z.B. auf die ungültige Adresse 00000000h. Danach weisst er bei der Zuweisung b keine Referenz zu, sondern b zeigt dann einfach auf den gleichen Speicherbereich. Das ist so als wenn du einem Pointer einen anderen zuweist - danach zeigen beide auf den gleichen Speicherbereich. Beide Variablen (a und b) bieten Platz für eine 32 Bit Adresse (daher ergibt SizeOf(a) bei beiden jeweils 4 Byte) - und beide haben ihren eigenen Speicherplatz von 4 Byte wo die sich diese Adresse drin merken. a liegt z.B. an Speicherstelle X und enthält als Adresse die Adresse einer Objektinstanz TT. Nun liegt Variable b an der Speicherstelle Y und enthält 0. Bei der Zuweisung werden einfach die 4 Byte der Variablen an der Speicherstelle Y mit dem gleichen Inhalt wie den der Speicherstelle X gleich gesetzt - also einmal umkopiert. Wenn du nun a Nil zuweist, dann wird in Speicherstelle X einfach eine 0 reingeschrieben - aber die Speicherstelle Y ist das doch egal - die hat nix mit a oder Speicherstelle X zu tun. Daher enthält danach die Speicherstelle Y immernoch den gleichen Inhalt.

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 von Jan
Und nach dem Prinzip dachte ich würde auch das funktionieren:

Delphi-Quellcode:
temp:=tstringlist(listview1.selected.data);
      freeandnil(temp);
Data ist ein Zeiger, und jetzt wird die Speicheradresse meines Objekts an Temp übergeben. Durch freeandnil wird der Speicherbereich meines Objekts freigegeben.

Richtig - du schreibst es selber richtig - die Speicheradresse wird übergeben - also nur die Adresse wo der Inhalt liegt.

Zitat:

Zitat von Jan
und demnach sollte dann auch
Delphi-Quellcode:
workarray[0]=nil
true liefern und keine AV.
Wo genau ist da jetzt mein Fehler?

Der liegt genau an dem Punkt zu erkennen (bzw. mir zu glauben :wink: ), dass Data von der ListView1.Selected einen eigenen Speicherplatz für diese Adresse vorhält auf die er zeigt wie Temp - der auch seinen eigenen Speicherplatz für die Adresse vorhält. Nach der Zuweisung beinhalten aber beide Speicherplätze die selbe Zahl (Adresse), aber sie liegen an unterschiedlichen Stellen.

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

Jan 20. Jan 2005 14:39

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:
      temp:=tstringlist(listview1.selected.data);
      freeandnil(temp);
      showmessage(workarray[0].strings[0]);
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.
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

Jan 20. Jan 2005 18:19

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

Muetze1 20. Jan 2005 23:41

Re: untypisierter pointer
 
Moin!

Zitat:

Zitat von Jan
Kann mir denn dabei wirklich keiner Helfen?
Müsste doch für die vielen erfahrenen Programmierer hier kein Problem sein, oder?

Nun mach mal kein Stress, es gibt Leute die arbeiten auch mal mehr als nur die üblichen 8 Stunden, daher kann es auch mal ein wenig dauern - und pushen innerhalb von 24 Stunden ist eh nicht gerne gesehen.

Zitat:

Zitat von Jan
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.

Ähm, also FreeAndNil() macht das so wie der Name schon sagt: er gibt erst das Objekt frei was an der Stelle steht wo die Instanzenvariable hinzeigt. Nun hat die Variable aber die Adresse noch wie zuvor, nur ein Zugriff auf diese führt zum Absturz, weil dort wo sie hinzeigt existiert kein Objekt mehr. Und damit das nicht passiert setzt die FreeAndNil() Funktion die Variable noch auf Nil, weil 0 ist eine ungültige Adresse und daher kann man nachprüfen ob das Objekt existiert - zumindest ob eine Adresse angegeben ist. Ich hatte mich bei FreeAndNil() nur auf den Nil Teil der Funktion bezogen - vorher gibt sie auch ordentlich das Objekt noch frei - das hatte ich oben in dem Zusammenhang weggelassen.

Zitat:

Zitat von Jan
Delphi-Quellcode:
a)     temp:=tstringlist(listview1.selected.data);
b)     freeandnil(temp);
c)     showmessage(workarray[0].strings[0]);

Soweit ich noch weiss, ist hier WorkArray[0] die gleiche StringList wie in ListView1.Selected.Data, richtig? Damit sind wir wieder bei dem oben genannten Problem:

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*

Jan 21. Jan 2005 00:51

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

Christian Seehase 21. Jan 2005 01:37

Re: untypisierter pointer
 
Moin Jan,

Zitat:

Zitat von Jan
dass freeandnil sowohl den Speicherbereich für die Variable, als auch den Speicherbereich für das Objekt, auf welches die Variable zeigt löscht,

nur dass Du es nicht missverstanden hast:
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 21:58 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 by Thomas Breitkreuz