Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Mehrdimensionales dynamisches Array, Element löschen (https://www.delphipraxis.net/158426-mehrdimensionales-dynamisches-array-element-loeschen.html)

schwa226 17. Feb 2011 08:53

Mehrdimensionales dynamisches Array, Element löschen
 
Hallo,

ich versuche gerade aus einem dynamischen Array ein Element zu löschen.

Dabei halte ich mich an dieses Beispiel:
Delphi-Quellcode:
type
  TIntArray = array of Integer;
procedure DeleteArrayElement(var AArray: TIntArray; const AIndex: Integer);
var
  i: Integer;
begin
  Move(AArray[AIndex + 1], AArray[AIndex], SizeOf(AArray[0]) * (Length(AArray) - AIndex - 1)); //Dahinterliegende Daten aufrücken
  SetLength(AArray, Length(AArray) - 1); // Länge kürzen
end;
Nun habe ich aber:
Delphi-Quellcode:
type
  TIntArray = array of array of Integer;
Wenn nun SetLength aufgrufen wird crashed es. Ich komme nicht drauf...

Bummi 17. Feb 2011 08:55

AW: Mehrdimensionales dynamisches Array, Element löschen
 
Als langjähriger Verfechter von Array würde ich inzwischen Listen bevorzugen....

schwa226 17. Feb 2011 09:00

AW: Mehrdimensionales dynamisches Array, Element löschen
 
Habe ich mir auch gedacht, aber dazu muss ich ja einen Pointer des Elemtes übergeben werden.
Dieses Element muss dann zuerst auch noch erzeugt und schließlich freigeben werden, oder?

Also so ca.:
Delphi-Quellcode:
Type
  TMyArray = class
    Index : Integer;
    Values : Array of Integer;
  end;
Dann mit Create erzeugen und mit Free wieder freigeben.

Neutral General 17. Feb 2011 09:04

AW: Mehrdimensionales dynamisches Array, Element löschen
 
Es gibt schon fertige Listen in Delphi.

1.
Delphi-Quellcode:
uses
  contnrs;

var
  liste: TObjectList; // oder TList für Nicht-Objekte
2.
Delphi-Quellcode:
uses
  Generics.Defaults, Generics.Collections;

var
  liste1: TList<Integer>; // In eckigen Klammern der Typ
  liste2: TObjectList<TButton>; // In eckigen Klammern der Typ (Klasse)
Gruß
Neutral General

schwa226 17. Feb 2011 09:10

AW: Mehrdimensionales dynamisches Array, Element löschen
 
Das TObjectList bringt mir jetzt nur, dass beim Delete auch das Element gleich freigegeben wird.
Zum Hinzufügen muss ich immer noch ein Create meiner TMyArray Class durchführen.

DeddyH 17. Feb 2011 09:14

AW: Mehrdimensionales dynamisches Array, Element löschen
 
Du kannst auch TList nehmen und dort Deine Arrays oder weitere Listen verwalten.

Neutral General 17. Feb 2011 09:15

AW: Mehrdimensionales dynamisches Array, Element löschen
 
Wofür soll deine TArrayClass überhaupt gut sein? :gruebel:

mleyen 17. Feb 2011 09:22

AW: Mehrdimensionales dynamisches Array, Element löschen
 
Delphi-Quellcode:
  procedure DeleteArrayElement(var AArray: TIntArray; const AIndex: Integer);
  begin
    SetLength(AArray[AIndex], 0);
    Move(AArray[AIndex + 1], AArray[AIndex], SizeOf(AArray[0]) * (Length(AArray) - AIndex - 1)); //Dahinterliegende Daten aufrücken
    SetLength(AArray, Length(AArray) - 1); // Länge kürzen
  end;
:?:

schwa226 17. Feb 2011 09:34

AW: Mehrdimensionales dynamisches Array, Element löschen
 
Zitat:

Zitat von Neutral General (Beitrag 1082399)
Wofür soll deine TArrayClass überhaupt gut sein? :gruebel:

Ich wüsste nicht wie es anders geht? Vielleicht geht es ja anders?

Mein Wissensstand zu TList:
Ich erzeuge ein Element, hier also TArrayClass.
Dies füge ich per List.Add(TArrayClass.Create) zur Liste hinzu.

Somit habe ich ähnliches zu einem Dynamischen Array mit der Ausnahme von der Möglichkeit von Delete, Move usw.

Ich könnte ja auch ein Record statt der Class machen.
Dann bei jedem neuen Element:
GetMem(MyElemnt, SizeOf(TArrayRecord));
List.Add(MyElemnt);

Wobei mir das mit GetMem weniger gefällt.

@mleyen:
Geht noch nicht so ganz:
http://postimage.org/image/4pod1bwk/

himitsu 17. Feb 2011 09:39

AW: Mehrdimensionales dynamisches Array, Element löschen
 
:!: Achtung, alle nachvollgenden Kodes sind speziell auf diese spezifische Datenstruktur ausgelegt.
(abgesehn von Code 2, welcher da "etwas" flexibler ist)
Delphi-Quellcode:
type
  TIntArray = array of array of Integer;
procedure DeleteArrayElement(var AArray: TIntArray; const AIndex: Integer);
var
  i: Integer;
begin
  AArray[AIndex] := nil; // daten löschen ... bei einem Einfachen Integer war das noch nicht wichtig
  Move(AArray[AIndex + 1], AArray[AIndex], SizeOf(AArray[0]) * (High(AArray) - AIndex));
  Pointer(AArray[High(AArray)]) := nil; // leeres Feld initialisieren, da sonst eine falsche Referens drinnensteht.
  SetLength(AArray, Length(AArray) - 1);
end;
oder
Delphi-Quellcode:
type
  TIntArrayX = array of Integer;
  TIntArray = array of TIntArrayX;
procedure DeleteArrayElement(var AArray: TIntArray; const AIndex: Integer);
var
  i: Integer;
  Temp: TIntArrayX;
begin
  Temp := AArray[AIndex]; // zwischenspeichern
  Move(AArray[AIndex + 1], AArray[AIndex], SizeOf(AArray[0]) * (High(AArray) - AIndex));
  Pointer(AArray[High(AArray)]) := nil; // leeres Feld initialisieren.
  AArray[High(AArray)] := Temp; // zurückspeichern ... SetLength gibt es dann frei
  SetLength(AArray, Length(AArray) - 1);
end;
oder
Delphi-Quellcode:
type
  TIntArray = array of array of Integer;
procedure DeleteArrayElement(var AArray: TIntArray; const AIndex: Integer);
var
  i: Integer;
  Temp: Pointer;
begin
  Temp := Pointer(AArray[AIndex]); // zwischenspeichern
  Move(AArray[AIndex + 1], AArray[AIndex], SizeOf(Pointer) * (High(AArray) - AIndex));
  Pointer(AArray[High(AArray)]) := Temp; // zurückspeichern (quasi mit AArray[AIndex] getauscht)
  SetLength(AArray, Length(AArray) - 1);
end;
Man bedenke, daß
Delphi-Quellcode:
array of Integer
ein Typ ist, dessen Speicher von Delphi verwaltet wird, außerdem liegen alle Daten außerhalb der Arraystruktur des übergeordneten Arrays, darum muß man sehr gut aufpassen, daß man an der Speicherverwaltung nix kaputt macht, wenn man da rumfummelt und die automatische Speicherverwaltung dermaßen umgeht.

Also, eine TList oder gar TList<...> kann da optimaler/einfacher sein.


Alle Zeitangaben in WEZ +1. Es ist jetzt 06:53 Uhr.
Seite 1 von 2  1 2      

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-2025 by Thomas Breitkreuz