dynamische Array, ähnlich String

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Antworten
Mathias
Beiträge: 6160
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

dynamische Array, ähnlich String

Beitrag von Mathias »

In FPC bauen sie gerade ein interessante Features ein.
Da kann man danamische Array addieren, so wie man es bei String auch gewohnt ist.

Dies scheint schon recht gut zu funktionieren.

Code: Alles auswählen

procedure Ausgabe(a: array of byte);
var
  i: integer;
begin
  for i := 0 to Length(a) - 1 do begin
    Write(a[i]: 4);
  end;
  WriteLn();
end;
 
procedure TForm1.Button1Click(Sender: TObject);
var
  a, b, c: array of byte;
  d: array[0..2] of byte = (6, 7, 8);
begin
  a := [1, 2, 3];
  Ausgabe(a);
 
  b := a + d + [123, 222];
  Ausgabe(b);
 
  c := b + b;
  Ausgabe(c);
 
//  d := [5, 6, 7];
end;


Hier macht er noch einen Fehler, "d" wird ignoriert, in der Ausgabe sehe ich nirgends 5, 6 oder 7.

Code: Alles auswählen

  b := a + d + [123, 222];


Dies wird gar nicht kompiliert, anscheinend geht dies bei statischen Arrays (noch ?) nicht.

Code: Alles auswählen

d := [5, 6, 7];
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

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: dynamische Array, ähnlich String

Beitrag von mschnell »

Das ist allerdings SUPER !

Für auf Byte-Basis arbeitende Kommunikations-Programme (mit irgendwelchen Partnern wie Modems, Hardware-Geräten, anderen Rechner via TCP/IP, ...) hat man früher gern einfach (ANSI-) Strings genommen. Mit dem Aufkommen von UTF-8 -Strings ging das wegen der drohenden automatischen Umwandlung nicht mehr (und in Delphi wegen UTF-16 Strings schon gar nicht).

Arrays of Bytes brauchten viel mehr User-Code.

Wenn nun die String-Operationen mit Array of Byte in String"-kompatibler weise funktionieren, lassen sich Kommunikationsprogramme viel leichter erstellen und portieren.

-Michael

Mathias
Beiträge: 6160
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: dynamische Array, ähnlich String

Beitrag von Mathias »

Ich habe einen Bug-Report, wegen des 6,7,8 Problemes geschrieben.

https://bugs.freepascal.org/view.php?id=33768

Wenn nun die String-Operationen mit Array of Byte in String"-kompatibler weise funktionieren

Delete funktioniert schon mal. :wink:
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Warf
Beiträge: 1908
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: Win10 | Linux
CPU-Target: x86_64

Re: dynamische Array, ähnlich String

Beitrag von Warf »

mschnell hat geschrieben:Das ist allerdings SUPER !

Für auf Byte-Basis arbeitende Kommunikations-Programme (mit irgendwelchen Partnern wie Modems, Hardware-Geräten, anderen Rechner via TCP/IP, ...) hat man früher gern einfach (ANSI-) Strings genommen. Mit dem Aufkommen von UTF-8 -Strings ging das wegen der drohenden automatischen Umwandlung nicht mehr (und in Delphi wegen UTF-16 Strings schon gar nicht).

Arrays of Bytes brauchten viel mehr User-Code.

Wenn nun die String-Operationen mit Array of Byte in String"-kompatibler weise funktionieren, lassen sich Kommunikationsprogramme viel leichter erstellen und portieren.

-Michael


Konnte man bislang sich nicht sowieso bereits die Operatoren selbst überschreiben?

Code: Alles auswählen

operator +(A, B: TByteArr)R: TByteArr;
begin
  SetLength(R, Length(A)+Length(B));
  Move(A[0], R[0], Length(A));
  Move(B[0], R[Length(A)], Length(B));
end;


Klar ist es mit einem bereits bestehenden operator angenehmer, aber diese 6 Zeilen würden mich jetzt nicht abhalten wenn ich das mehr als einmal brauchen würde

Mathias
Beiträge: 6160
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: dynamische Array, ähnlich String

Beitrag von Mathias »

Konnte man bislang sich nicht sowieso bereits die Operatoren selbst überschreiben?

Dies geht sogar einfacher, da der Speicher nur einmal kopiert werden muss, vorausgesetzt es hat hinter der bestehenden Array genügend Speicher frei.

Code: Alles auswählen

  operator +(A, B: TByteArr)R: TByteArr;
  begin
    R := A;
    SetLength(R, Length(A) + Length(B));
    Move(B[0], R[Length(A)], Length(B));
  end;   

Ist nur der Fall, wen man x := x + y macht
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Socke
Lazarusforum e. V.
Beiträge: 3158
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: dynamische Array, ähnlich String

Beitrag von Socke »

Mathias hat geschrieben:Dies geht sogar einfacher, da der Speicher nur einmal kopiert werden muss, vorausgesetzt es hat hinter der bestehenden Array genügend Speicher frei.

Kann man den Speichermanager anweisen, den Array mit den geringsten Kosten (d.h. ohne Kopieren oder den kleineren Array) zu erweitern?
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

Mathias
Beiträge: 6160
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: dynamische Array, ähnlich String

Beitrag von Mathias »

Kann man den Speichermanager anweisen, den Array mit den geringsten Kosten (d.h. ohne Kopieren oder den kleineren Array) zu erweitern?
Macht diese Verwaltung nicht das OS ?

Ich hatte mal ein Testprogramm geschrieben, das eine Array immer ein Element hinzugefügt hatte. Dabei hatte ich die Zeit gemessen und dies in ein TChart geschrieben.
Da sah man gut, das der Speicher zwischendurch umkopiert wurde. Je grösser die Array wurde je grösser wurden die Kopierzeiten.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
corpsman
Lazarusforum e. V.
Beiträge: 1496
Registriert: Sa 28. Feb 2009, 08:54
OS, Lazarus, FPC: Linux Mint Mate, Lazarus GIT Head, FPC 3.0
CPU-Target: 64Bit
Wohnort: Stuttgart
Kontaktdaten:

Re: dynamische Array, ähnlich String

Beitrag von corpsman »

Für interessierte mit meinem Programm Heapsim könnt ihr die verschiedenen Allokationsalgorithmen gegen die verschieden Haldenverwaltungsstrategieen testen.

FPC nutzt meines Erachtens eine Mischung aus Buddyheap und Next fit
--
Just try it

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: dynamische Array, ähnlich String

Beitrag von mschnell »

Warf hat geschrieben:Konnte man bislang sich nicht sowieso bereits die Operatoren selbst überschreiben?

Socke hat geschrieben:Kann man den Speichermanager anweisen, den Array mit den geringsten Kosten (d.h. ohne Kopieren oder den kleineren Array) zu erweitern?

Strings machen "Lazy Copy" und Reference Counting was natürlich sehr effektiver ist.

Ich weiß nicht, ob das bei bei dynamischen Arrays dann auch implementiert wird.

Ich hatte vor längerer Zeit mal in der developers mailing List den Vorschlag gemacht (und im Wiki ziemlich detailliert ausgeführt), zusäzulich zu den diversen bereits vorhandenen "dynamischen" String Typen auch nicht konvertierbare für Bytes (und 16, 32, und 64 Bit Wörter) zu implementieren. Da schien aber kein Interesse dran zu sein.

Das halte ich immer noch für die bessere Lösung als "Byte Array".

-Michael

Mathias
Beiträge: 6160
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: dynamische Array, ähnlich String

Beitrag von Mathias »

Es ist noch was tolles dazu gekommen, man muss nicht mehr die grösser der Array von Anfang an wissen, wen vorbelegen will.

Code: Alles auswählen

// alt
  d_static: array[0..2] of byte = (6, 7, 8);
// neu
  d_dynamic: array of byte = (6, 7, 8);


Das nachträgliche Ändern kann man mit $J- unterbinden, so wie man es bei const gewöhnt ist.

Code: Alles auswählen

const
  d_dynamic: array of byte = (6, 7, 8);
  {$push}
  {$J-}
  e_dynamic: array of byte = (6, 7, 8);
  {$push}
 
begin
  a := [1, 2, 3];
  Ausgabe(a);           // io.
 
  SetLength(d_dynamic, 4);
  SetLength(e_dynamic, 4)// Erzeugt Kompilerfehler


Unter ./fpc/tests/test in den fpc-sourcen, findet man noch mehr Beispiele.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

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: dynamische Array, ähnlich String

Beitrag von mschnell »

Mathias hat geschrieben:Es ist noch was tolles dazu gekommen, man muss nicht mehr die grösser der Array von Anfang an wissen, wen vorbelegen will.

Wie bei Strings....

Ich fürchte allerdings dass bei dynamischen Arrays

a := b;
b[1] := '1';

nicht zum "lazy copy" führt, also (anders als bei Strings) nun a[1] ebenfalls verändert ist.

Es wäre schön, wenn sich hier String-kompatibles Verhalten anwählen ließe.

-Michael

Mathias
Beiträge: 6160
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: dynamische Array, ähnlich String

Beitrag von Mathias »

Es ist noch was tolles dazu gekommen, man muss nicht mehr die grösser der Array von Anfang an wissen, wen vorbelegen will.

Code: Alles auswählen

// alt
  d_static: array[0..2] of byte = (6, 7, 8);
// neu
  d_dynamic: array of byte = (6, 7, 8);

Dies wurde momentan wieder entfernt, ich hoffe das es nicht so bleibt.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Mathias
Beiträge: 6160
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: dynamische Array, ähnlich String

Beitrag von Mathias »

Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Antworten