[gelöst] Zuweisung von Objekten: Zeiger oder Adresse

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Scotty
Beiträge: 768
Registriert: Mo 4. Mai 2009, 13:24
OS, Lazarus, FPC: Arch Linux, Lazarus 1.3 r44426M FPC 2.6.4
CPU-Target: x86_64-linux-qt/gtk2
Kontaktdaten:

[gelöst] Zuweisung von Objekten: Zeiger oder Adresse

Beitrag von Scotty »

Ich speichere Objekte in einer Liste und verschiebe die in ein dynamisches Feld. In etwa so:

Code: Alles auswählen

type
  TTestData=class
    x,y :byte
  end;
  TTest1=class
    FList:TList;
    constructor Create;
  end;
  TTest2=class
    FTestData:array of array of TTestData;
    constructor Create;
  end;
end;  
constructor TTest1.Create()
var tmp:TTestData
begin
  inherited;
  FList:=TList.Create;
  for i:=0 to 9 do 
  begin
    tmp:=TTestData.Create;
    FList.Add(tmp); 
  end;
end;
constructor TTest2.Create()
begin
  inherited;
  setlength (FTestData,10,10);
end;
//----------------
procedure MoveData(aValue:TTestData; const hinher:boolean);
begin
  if hinher then 
  begin
    Test2.FTestData[aValue.x,aValue.y]:=aValue;
    Test1.FList.Delete[Test1.FList.IndexOf(aValue)];
  end else
  begin 
    Test1.FList.Add(aValue);
    Test2.FTestData[aValue.x,aValue.y]:=nil;
  end;
end;
Mal abgesehen davon, dass es eher Pseudocode ist und sicher Tippfehler dabei sind - die Zuweisung eines Objektes aus einer Liste bezieht sich doch nur auf den Zeiger, IMHO. Und wenn ich das Objekt im dynamischen Array auf nil setze, sollte es doch weg sein. Oder? Mein Code funktioniert meistens, aber scheinbar nicht immer - schwer zu debuggen.

TIA, Scotty.
Zuletzt geändert von Scotty am Mi 17. Jun 2009, 17:11, insgesamt 1-mal geändert.

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Re: Zuweisung von Objekten: Zeiger oder Adresse

Beitrag von mschnell »

Wie meinst Du "weg sein" ?

Wenn Du den Zeiger auf das Objekt = NIL setzt, ist es nicht mehr zugreifbar (sofern kein anderer Zeiger darauf existiert). Wenn es den speicher freigeben soll, musst Du Object.Free aufrufen.

-Michael

Scotty
Beiträge: 768
Registriert: Mo 4. Mai 2009, 13:24
OS, Lazarus, FPC: Arch Linux, Lazarus 1.3 r44426M FPC 2.6.4
CPU-Target: x86_64-linux-qt/gtk2
Kontaktdaten:

Re: Zuweisung von Objekten: Zeiger oder Adresse

Beitrag von Scotty »

Dir Frage ist, ob ich so etwas falsch mache. In einem Testlauf kommt es jedenfalls vor, dass die Felder nicht nil sind, bzw. dass an anderer Stelle etwas unsauber läuft.

Benutzeravatar
theo
Beiträge: 11369
Registriert: Mo 11. Sep 2006, 19:01

Re: Zuweisung von Objekten: Zeiger oder Adresse

Beitrag von theo »

Scotty hat geschrieben:Dir Frage ist, ob ich so etwas falsch mache.
Wie soll man das denn anhand deines "Pseudocodes" erkennen?
Wo weist du denn x und y überhaupt Werte zu?

Scotty
Beiträge: 768
Registriert: Mo 4. Mai 2009, 13:24
OS, Lazarus, FPC: Arch Linux, Lazarus 1.3 r44426M FPC 2.6.4
CPU-Target: x86_64-linux-qt/gtk2
Kontaktdaten:

Re: Zuweisung von Objekten: Zeiger oder Adresse

Beitrag von Scotty »

Schon klar, dass mein Beispiel sehr vereinfacht ist. Die Eigenschaften wie x und y werden richtig gesetzt.
Wenn ich eine Variable p:Pointer deklariere und mit p:=@data zuweise, dann sind doch, vorausgesetzt alles wird richtig gemacht, in p alle Daten enthalten. Wenn ich p auf nil setze, wird dadurch data zerstört? Ich denke dabei an solche Dinge wie vertauschte Zeilen in meinem Beispiel, d.h. erst Test2.FTestData[aValue.x,aValue.y]:=nil; und dann Test1.FList.Add(aValue);.

Benutzeravatar
theo
Beiträge: 11369
Registriert: Mo 11. Sep 2006, 19:01

Re: Zuweisung von Objekten: Zeiger oder Adresse

Beitrag von theo »

Scotty hat geschrieben:Wenn ich eine Variable p:Pointer deklariere und mit p:=@data zuweise, dann sind doch, vorausgesetzt alles wird richtig gemacht, in p alle Daten enthalten. Wenn ich p auf nil setze, wird dadurch data zerstört?
Diese Frage hat mschnell schon beantwortet. P ist nur ein Zeiger auf die Speicherstelle wo das Objekt sitzt.
Du kannst hunderte davon auf ein einziges Objekt zeigen lassen und alle anschliessend Nil setzen, das Objekt (der Speicher) wird dadurch nicht freigegeben, das geht nur mit Obj.free.

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Re: Zuweisung von Objekten: Zeiger oder Adresse

Beitrag von mschnell »

Scotty hat geschrieben:Wenn ich eine Variable p:Pointer deklariere und mit p:=@data zuweise, dann sind doch, vorausgesetzt alles wird richtig gemacht, in p alle Daten enthalten.
Bitte lies erst 'mal nach, was ein Zeiger ist....

-Michael.

Socke
Lazarusforum e. V.
Beiträge: 3192
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: Zuweisung von Objekten: Zeiger oder Adresse

Beitrag von Socke »

mschnell hat geschrieben:
Scotty hat geschrieben:Wenn ich eine Variable p:Pointer deklariere und mit p:=@data zuweise, dann sind doch, vorausgesetzt alles wird richtig gemacht, in p alle Daten enthalten.
Bitte lies erst 'mal nach, was ein Zeiger ist....

-Michael.
Das lustige ist, dass C++ genau so etwas kann. Also Objekte freigeben, wenn deren Gültigkeit abhanden kommt (geht nur mit automatisch erstellten Objekten). Eine Alternative wäre ein Garbage-Collector. Aber beides gibts nicht in Pascal.

Eine Möglichkeit wäre, die Freigabe der Objekte zu automatisieren:

Code: Alles auswählen

procedure TSomeClass.SetSomeProperty(AFooValue: TBarObject);
begin
// a ist unser Feld oder Array-Feld oder was weiß ich
  if a = AFooValue then exit;
  // bei Objekten:
  a.Free;
  // bei Records:
  Dispose(a);
 // und neuen Wert (nil) einfügen
 a := AFooValue;
end;
Noch ein Tipp: Um zu überprüfen, ob Du alles korrekt freigegeben hast, kannst Du die Unit heaptrc verwenden.

MfG Socke
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

Benutzeravatar
theo
Beiträge: 11369
Registriert: Mo 11. Sep 2006, 19:01

Re: Zuweisung von Objekten: Zeiger oder Adresse

Beitrag von theo »

Socke hat geschrieben: Das lustige ist, dass C++ genau so etwas kann. Also Objekte freigeben, wenn deren Gültigkeit abhanden kommt (geht nur mit automatisch erstellten Objekten). ... Aber beides gibts nicht in Pascal.
Mit Interfaces (referenzgezählt) kann Delphi/FPC das auch.

Socke
Lazarusforum e. V.
Beiträge: 3192
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: Zuweisung von Objekten: Zeiger oder Adresse

Beitrag von Socke »

theo hat geschrieben:
Socke hat geschrieben:Mit Interfaces (referenzgezählt) kann Delphi/FPC das auch.
Wo gibt es denn etwas tiefer gehende Literatur darüber, wie man Interfaces benutzt (und fast noch wichtiger: selbst erstellt)?
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

Benutzeravatar
theo
Beiträge: 11369
Registriert: Mo 11. Sep 2006, 19:01

Re: Zuweisung von Objekten: Zeiger oder Adresse

Beitrag von theo »

Socke hat geschrieben: Wo gibt es denn etwas tiefer gehende Literatur darüber, wie man Interfaces benutzt (und fast noch wichtiger: selbst erstellt)?
Gibt's tonnenweise im Internet. Einfach Delphi und Interfaces oder InterfacedObject suchen.

Eine einfache Variante geht etwa so:

Code: Alles auswählen

{ ITest }
ITest = Interface
  procedure DoSth;
end;
 
{ TTest }
TTest = class(TInterfacedObject, ITest)
  public
    procedure DoSth;
  end;
 
 
var
  Form1: TForm1; 
 
implementation
 
{ TTest }
 
procedure TTest.DoSth;
begin
  Form1.Caption:=TimeToStr(Now);
end;
 
{ TForm1 }
 
procedure TForm1.Button1Click(Sender: TObject);
var TestIntf:ITest;
begin
  TestIntf:=TTest.Create;
  TestIntf.DoSth;
  //TestIntf müsste sich autom. befreien.
end;

Socke
Lazarusforum e. V.
Beiträge: 3192
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: Zuweisung von Objekten: Zeiger oder Adresse

Beitrag von Socke »

theo hat geschrieben:
Socke hat geschrieben: Wo gibt es denn etwas tiefer gehende Literatur darüber, wie man Interfaces benutzt (und fast noch wichtiger: selbst erstellt)?
Gibt's tonnenweise im Internet. Einfach Delphi und Interfaces oder InterfacedObject suchen.
Danke. Vielleicht hätte ich in meinen Versuchen auch TInterfacedObject nehmen sollen :oops:, dann hätten die vielleicht auch funktioniert.

MfG Socke
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Re: Zuweisung von Objekten: Zeiger oder Adresse

Beitrag von mschnell »

theo hat geschrieben:
Socke hat geschrieben: Das lustige ist, dass C++ genau so etwas kann. Also Objekte freigeben, wenn deren Gültigkeit abhanden kommt (geht nur mit automatisch erstellten Objekten). ... Aber beides gibts nicht in Pascal.
Mit Interfaces (referenzgezählt) kann Delphi/FPC das auch.
Bei Delphi-Prism und C# gibt's gar kein free. Da macht das .NET / Mono Framework die Referenz-Überprüfung automatisch. Ich vermute dasselbe gilt für andere Frameworks wie Java und Python genauso.

-Michael

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 7389
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Zuweisung von Objekten: Zeiger oder Adresse

Beitrag von af0815 »

mschnell hat geschrieben:Bei Delphi-Prism und C# gibt's gar kein free. Da macht das .NET / Mono Framework die Referenz-Überprüfung automatisch.
Bei C# hast du definitiv einen Garbage Collector mit all seinen Vorteilen und Nachteilen. EIner der Vorteile ist, das du dich weniger um Deine Objekte kümmern musst, der Nachteil ist, das du relativ wenig Einfluß hast, wann deine Objekte zerstört werden (man kann es aber kontrollieren). Das kann bei Bildauswertungen im Verbund mit getakteten Maschinen oft sehr störend sein und eine dubiose Quelle von azyklischen Maschinenstops. Im normalen Betrieb überwiegt der Vorteil von dem Automatismus.

Ich liebe an Pascal das Verhalten, das ich mich um meine Objekte kümmern muß, da da das Verhalten sehr vorhersehbar ist.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Re: Zuweisung von Objekten: Zeiger oder Adresse

Beitrag von mschnell »

af0815 hat geschrieben:Ich liebe an Pascal das Verhalten, das ich mich um meine Objekte kümmern muß, da da das Verhalten sehr vorhersehbar ist.
Der Garbage--Collector kann natürlich riesige Wartezeiten produzieren. Die Philisophie bei .NET ist: wir haben sehr viel RAM und brauchen keine Garbage-Collect zu machen bevor das Programm beendet wird (oder der Rechner abstürzt :twisted: ).

-Michael

Antworten