AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Dynamische Arrays "zu Fuß"

Ein Thema von Luckie · begonnen am 20. Dez 2003 · letzter Beitrag vom 28. Dez 2003
Antwort Antwort
Seite 1 von 4  1 23     Letzte »    
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#1

Dynamische Arrays "zu Fuß"

  Alt 20. Dez 2003, 19:51
Dynamische Arrays sind ja erst ab D4 und höher bekannt. Aber es gibt ja schon unter D3 Stringliste, was ja im Endeffekt auch nur ein dynmaisches Array of String ist. Da ich damit leibäugle mir D3 Professional ("Delphi for Kids" läßt grüßen) zu kaufen und ich des öfteren doch auf dynamische Arrays angewiesen bin, wollte ich mal fragen, wie man dynamische Arrays zu Fuß, also selber erstellt.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Chewie

Registriert seit: 10. Jun 2002
Ort: Deidesheim
2.886 Beiträge
 
Turbo Delphi für Win32
 
#2

Re: Dynamische Array "zu Fuß"

  Alt 20. Dez 2003, 20:02
Dynamische Arrays funktionieren ja so, dass bei einem Aufruf von SetLength() soviel Speicher alloziert wird, wie das Array benötigt (also Länge des Array * Elementgröße). Der Zugriff auf ein Speicherelement erfolgt mit der Formel Startadressse + Index * Elementgröße. Bei jedem Aufruf von SetLength wird nun das Array an einen anderen Speicherplatz kopiert und der alte Speicher freigegeben. Pack das ganze in eine schöne Klasse und das sollte es gewesen sein.
OK, du musst für jeden Datentyp eine eigene Implementierung machen, aber das dürfte weitgehend mit C&P zu lösen sein.

So mal ein Beispiel, wie der Umgang mit diesem Objekt wäre. Die Daten selbst wären über einen Pointer abgespeichert, außerdem muss die Anzahl der Einträge gespeichert werden.

Delphi-Quellcode:
//die Klasse heißt TDynArray
myArray := TDynArray.Create(1); //Array mit der Länge erzeugen, im Konstruktor Aufruf von SetLength
myArray[0] := myVar; //myVar an Startposition + 0 schreiben
myArray.SetLength(2); //jetzt werden die ganzen Daten des Array an eine neue Speicherstelle kopiert
myArray.Free;
SetLength würde folgendes tun:
- NeueLänge * Elementgröße Bytes Speicher allozieren
- AlteLänge * Elementgröße Bytes ausgehend von DataPointer in neuen Speicher kopieren
- DataPointer mit alter Länge freigeben
- DataPointer bekommt die Adresse des neuen Speicherbereichs
- Fallunterscheidung: bei Länge 0 kein Kopieren nötig.

Der Zugriff auf ein Element:
- Die Adresse Index * Elementgröße + Datapointer dereferenzieren und in entsprechenden Typ casten

So könnte man das lösen.
Martin Leim
Egal wie dumm man selbst ist, es gibt immer andere, die noch dümmer sind
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#3

Re: Dynamische Array "zu Fuß"

  Alt 20. Dez 2003, 20:18
Ich habe mal versucht das irgendwie umzusetzten, nach einen Tipp von tommie-lie, der hat sich aber leider unter die Dusche verdrückt.

Bitte nicht lachen, mit Zeigern habe ich es nicht so.
Delphi-Quellcode:
type
  PString = ^String;

var
  StringArray: PString;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  GetMem(StringArray, sizeof(StringArray)+1*sizeof(PString));
  PString(StringArray)^ := Edit1.Text;
end;
Ich bekomme allerdings eine AccessViolation.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Benutzerbild von Jens Schumann
Jens Schumann

Registriert seit: 27. Apr 2003
Ort: Bad Honnef
1.644 Beiträge
 
Delphi 2009 Professional
 
#4

Re: Dynamische Arrays "zu Fuß"

  Alt 20. Dez 2003, 20:28
Hallo Luckie,
möchtest Du wirklich dyn. Array verwenden oder machst Du das nur aus interesse ?
TList liefert eigentlich schon alles was Du brauchst. Wenn Du auf max. Geschwindigkeit
aus bist dann versuche es mit einer verketteten Liste (beispiele finden sich überall).

Ich bin noch nie in eine Situation gekommen die ich nur mit einem dyn. Array lösen konnte.
Deshalb behaupte ich:

!!! Dyn. Array braucht keiner!!!

Ich glaube die dyn. Array's wurden nur für Basic-Programmierer in Delpih aufgenommen.
  Mit Zitat antworten Zitat
Hansa

Registriert seit: 9. Jun 2002
Ort: Saarland
7.554 Beiträge
 
Delphi 8 Professional
 
#5

Re: Dynamische Arrays "zu Fuß"

  Alt 20. Dez 2003, 20:37
Zitat von Jens Schumann:
Ich bin noch nie in eine Situation gekommen die ich nur mit einem dyn. Array lösen konnte.
Deshalb behaupte ich:

!!! Dyn. Array braucht keiner!!!

Ich glaube die dyn. Array's wurden nur für Basic-Programmierer in Delpih aufgenommen.
Dem ist voll zuzustimmen ! Ich zumindest verwende ein starres Array, sofern die Anzahl der Elemente vorher klar ist, oder direkt verkettete Listen. Dynamische Arrays hängen irgendwie dazwischen. Aber: ist bspw. ein StringGrid nicht auch ein dyn. Array ?
Gruß
Hansa
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#6

Re: Dynamische Arrays "zu Fuß"

  Alt 20. Dez 2003, 20:40
Nun ja, interesse und weil D3 keine dynamischen Arrays kennt.

Mit TList habe ich noch nie gearbeitet. Kennt das D3 denn? Und wie ginge es damit?
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Benutzerbild von Jens Schumann
Jens Schumann

Registriert seit: 27. Apr 2003
Ort: Bad Honnef
1.644 Beiträge
 
Delphi 2009 Professional
 
#7

Re: Dynamische Arrays "zu Fuß"

  Alt 20. Dez 2003, 20:43
Hallo Luckie
Zitat von Luckie:
Mit TList habe ich noch nie gearbeitet. Kennt das D3 denn?
TList gibt es schon seit D1.

TList ist in der Delphi-Hilfe bestens dokumentiert.
  Mit Zitat antworten Zitat
Chewie

Registriert seit: 10. Jun 2002
Ort: Deidesheim
2.886 Beiträge
 
Turbo Delphi für Win32
 
#8

Re: Dynamische Arrays "zu Fuß"

  Alt 20. Dez 2003, 20:47
Ich würds gar nicht so kompliziert machen und auf einen Typ ausrichte.

Hab hier mal was kleines geschrieben, so wie ichs mir vorstelle:

Delphi-Quellcode:
unit DynArray;

interface
  TDynArray = class
  private
    FDataPointer: Pointer;
    FElementSize: Integer;
    FDataSize: Integer;
    function GetValue(Index: Integer): Integer;
    procedure SetValue(Index: Integer; const Value: Integer);
    procedure CopyData(Destination: Pointer; Size: Integer);
  public
    constructor Create(InitialLength: Integer);
    destructor Destroy; override;
    property Value[Index: Integer]: Integer read GetValue write SetValue;
    procedure SetLength(NewLength: Integer);
  end;

const
  ElementSize = sizeof(Integer);

implementation

{ TDynArray }

procedure TDynArray.CopyData(Destination: Pointer; Size: Integer);
begin
  CopyMemory(Destination, FDataPointer, Size);
end;

constructor TDynArray.Create(InitialLength: Integer);
begin
  FElementSize := ElementSize;
  FDataPointer := nil;
  FDataSize := 0;
  SetLength(InitialLength);
end;

destructor TDynArray.Destroy;
begin
  SetLength(0);
end;

function TDynArray.GetValue(Index: Integer): Integer;
begin
  if Index > Pred(FDataSize) then
    //irgendeine Exception oder sowas auslösen
  Result := Integer(Pointer(Integer(FDataPointer) + Index * FElementSize)^);
end;

procedure TDynArray.SetLength(NewLength: Integer);
var
  NewData: Pointer;
begin
  if NewLength <> 0 then
    FreeMem(FDataPointer, FDataSize * FElementSize);
  GetMem(NewData, NewLength * FElementSize);
  if FDataSize <> 0 then
    CopyData(NewData, FDataSize * FElementSize);
  FreeMem(FDataPointer, FDataSize * FElementSize);
  FDataPointer := NewData;
end;

procedure TDynArray.SetValue(Index: Integer; const Value: Integer);
begin
  if Index > Pred(FDataSize) then
    //irgendeine Exception oder sowas auslösen
  Integer(Pointer(Integer(FDataPointer) + Index * FElementSize)^) := Value;
end;

end.
Martin Leim
Egal wie dumm man selbst ist, es gibt immer andere, die noch dümmer sind
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#9

Re: Dynamische Arrays "zu Fuß"

  Alt 20. Dez 2003, 21:04
So, nach der Anregung von Herrn Schumann die Lösung mit TList:
Delphi-Quellcode:
type
  StringArray = record
    MyString: String;
  end;
  PStringArray = ^StringArray;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  MyList: Tlist;
  sa: PStringArray;
  Loop: Integer;
begin
  MyList := TList.Create;
  try
    New(sa);
    sa.MyString := 'Egon';
    MyList.Add(sa);
    New(sa);
    sa.MyString := 'Klaus';
    MyList.Add(sa);
    New(sa);
    sa.MyString := 'Michaela';
    MyList.Add(sa);
    for Loop := 0 to myList.Count-1 do
    begin
      sa := MyList.Items[Loop];
      Listbox1.Items.Add(sa.MyString);
    end;
    for Loop := 0 to MyList.Count-1 do
    begin
      sa := MyList.Items[Loop];
      Dispose(sa);
    end;
  finally
    FreeAndNil(MyList);
  end;
end;
Eigentlich auch so in der Hilfe zu finden.

Zu beahcten ist nur, dass man vor dem Hinzufügen, neuen Speicher reserviert (New) für den Record und nach Gebrauch selbigen wieder frei gibt (Dispose). Ist eventuell etwas umständlicher, dafür ist man mit dem Zeiger auf den Record aber felxibeler, man kann mehr Speichern und muss nicht auf mehrdimensionale Arrays zurückgreifen.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Chewie

Registriert seit: 10. Jun 2002
Ort: Deidesheim
2.886 Beiträge
 
Turbo Delphi für Win32
 
#10

Re: Dynamische Arrays "zu Fuß"

  Alt 20. Dez 2003, 21:06
Zitat:
Ist eventuell etwas umständlicher, dafür ist man mit dem Zeiger auf den Record aber felxibeler
Wieso flexibler? Man kann auch ein Array of Pointer oder sogar ein Array of PStringArray nehmen. Dann spart man sich sogar das Typisieren.
Martin Leim
Egal wie dumm man selbst ist, es gibt immer andere, die noch dümmer sind
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 4  1 23     Letzte »    


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:00 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz