Position vom einfügen bei copy von dyn. Array bestimmen?

Für Fragen von Einsteigern und Programmieranfängern...
Antworten
u-boot
Beiträge: 308
Registriert: Do 9. Apr 2009, 10:10
OS, Lazarus, FPC: Ubuntu 9.10 (L 0.9.28 FPC 2.2.4)
CPU-Target: 32Bit
Wohnort: 785..

Position vom einfügen bei copy von dyn. Array bestimmen?

Beitrag von u-boot »

Code: Alles auswählen

type TPointArr:Array of TPoint
var PointArr1: TPointArr;
var PointArr2: TPointArr;
//...
PointArr1:=copy(PointArr2);
//...
nun ist der Startindex des kopierten Teils von PointArr1 jedoch bei 0.
ich hätte gern an der Position 0 noch nen anderen Wert eingefügt und das ezufügende dann eine Position weiter nach hinten.

Probiert habe ich mal die Move-Procedure... da waren die Ergebnisse aber etwas falsch.
Weiss jemand hier vielleicht ne elegantere Lösung als mit ner Schleife jeden Wert einzeln zu übertragen?
Ubuntu 9.10 (L 0.9.28 FPC 2.4.x)

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

Re: Position vom einfügen bei copy von dyn. Array bestimmen?

Beitrag von theo »

Naja, ich verwende immer gerne TList, weil da das ganze Array Pipapo schon gemacht ist.
Ich hab mal ein Beispiel wie das gehen könnte, ohne TList zu überschreiben, was natürlich noch sauberer wäre.
Sieht vielleicht auf den ersten Blick etwas kompliziert aus, aber du kannst so auf alle Methoden von TList zugreifen.
ACHTUNG: Hier werden Pointer auf TPoint kopiert!!! keine Werte. D.h. Liste1 zeigt auf die gleichen TPoint wie Liste2.
Deshalb darfst du die auch in L1 nicht freigeben.
Wenn du das nicht willst, kannst du schon mit deinem Ansatz und Move arbeiten. Auch hier zeigt dir der Sourcecode von TList wie das geht. Sonst mit TList die Werte wirklich einzeln kopieren.

Code: Alles auswählen

uses types;      
 
Procedure TForm1.Button1Click(Sender:TObject);
Var L1,L2: TList;
  pt: PPoint;
  i: integer;
Begin
  L1 := TList.Create;
 
  new(pt);
  pt^ := Point(10,20);
  L1.Add(pt);
 
  new(pt);
  pt^ := Point(20,50);
  L1.Add(pt);
 
  L2 := TList.Create;
  L2.Assign(L1);
  L1.free;
 
  new(pt);
  pt^ := Point(30,80);
  L2.Insert(0,pt);
 
  For i:=0 To L2.Count-1 Do
    writeln(PPoint(L2[i])^.X,' ',PPoint(L2[i])^.Y);
 
  For i:=0 To L2.Count-1 Do
    Dispose(PPoint(L2[i]));
  L2.free;
End;

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

Re: Position vom einfügen bei copy von dyn. Array bestimmen?

Beitrag von theo »

Mit deinem Ansatz müsste es so gehen:

Code: Alles auswählen

Procedure TForm1.Button2Click(Sender:TObject);
Type TPointArr = Array Of TPoint;
 
Var PointArr1: TPointArr;
  PointArr2: TPointArr;
  i: integer;
Begin
  SetLength(PointArr1,2);
  PointArr1[0] := Point(10,10);
  PointArr1[1] := Point(20,20);
 
  SetLength(PointArr2,High(PointArr1)+2);
  Move(PointArr1[0],PointArr2[1],(High(PointArr1)+1)*SizeOf(TPoint));
  Finalize(PointArr1);
  PointArr2[0] := Point(30,30);
 
  For i:=0 To High(PointArr2) Do
    writeln(PointArr2[i].X,' ',PointArr2[i].Y);
End;

u-boot
Beiträge: 308
Registriert: Do 9. Apr 2009, 10:10
OS, Lazarus, FPC: Ubuntu 9.10 (L 0.9.28 FPC 2.2.4)
CPU-Target: 32Bit
Wohnort: 785..

Re: Position vom einfügen bei copy von dyn. Array bestimmen?

Beitrag von u-boot »

wahnsinn .... vielen Dank für die Ausführliche Antwort

mir hat wohl das mit dem Sizeof gefehlt ... ahja und finalize ist eigentlich auch nicht so in meinem repertoire aber könnt sich ja nun ändern :)
Ubuntu 9.10 (L 0.9.28 FPC 2.4.x)

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

Re: Position vom einfügen bei copy von dyn. Array bestimmen?

Beitrag von theo »

u-boot hat geschrieben:ahja und finalize ist eigentlich auch nicht so in meinem repertoire aber könnt sich ja nun ändern :)
Finalize ist nicht unbedingt nötig, da dynamische Arrays referenzgezählt sind, und automatisch freigegeben werden, wenn sie nicht mehr gebraucht werden.
Dass ich es trotzdem eingebaut habe, ist wohl eine Krankheit von mir, bestimmen zu wollen, wann das geschieht und dass das sicher geschieht. ;-)
Ich hab's halt nicht so mit Garbage Collection and friends ;-)

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

Re: Position vom einfügen bei copy von dyn. Array bestimmen?

Beitrag von theo »

Noch was: Move ist eine ziemliche low-level Prozedur.
Es kopiert einfach eine Anzahl Bytes von Speicherblock A nach Speicherblock B.
Das geht sauschnell, aber du bist verantworlich dafür, dass die Anzahl Bytes richtig berechnet wurde und dass im Ziel genügend Speicher reserviert wurde.
Move schützt dich da vor gar nichts. Das kann auch ordentlich in die Hose gehen.

Antworten