Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Dynamisches Array (https://www.delphipraxis.net/154241-dynamisches-array.html)

Lotus 2. Sep 2010 14:06

Delphi-Version: 2007

Dynamisches Array
 
Hallo ich habe ein dynmaisches Array
Delphi-Quellcode:
A : array of TKarte
TKarte ist dafür unwichtig, könnten auch Bytes oder Integer sein, ist egal.

Aber jetzt kommt ein Fehler wenn ich Daten ins Array fügen will..
Die setLength des Array's ist am Anfang auf 0.. dann rufe ich folgende Procedure auf:
Delphi-Quellcode:
procedure cardToArray(karte:TKarte; KartenArray:array of TKarte);
var laenge:Byte;
begin
laenge:=length(KartenArray); //muesste 0 sein beim ersten aufruf
setLength(KartenGezogen, laenge+1); //hier setze ich die laenge auf 1
KartenArray[laenge]:=karte; //und hier füge ich an indexposition [0] die daten ein
end;
Da meckert Delphi rum mit der Exception:
ERangeError: Fehler bei der Bereichsüberprüfung...

Ich versteh's nicht.. die Grenzen sind doch richtig gesetzt oder nicht?

Klaus01 2. Sep 2010 14:10

AW: Dynamisches Array
 
Hallo,

die Meldung kommt vielleicht weil Length keine Byte-Typen
liefert.

Grüße
Klaus

Lotus 2. Sep 2010 14:20

AW: Dynamisches Array
 
Danke für deine Antwort,
Fehler tritt aber leider auch bei Integer auf.

blauweiss 2. Sep 2010 14:25

AW: Dynamisches Array
 
Hallo Lotus,

der Fehler ist garantiert, weil Du zwar array "KartenArray" übergibst und in dieses einfügen willst, aber nur ein anderes (globales ??) array "KartenGezogen" größer dimensionierst.

Gruss
blauweiss

Lotus 2. Sep 2010 14:34

AW: Dynamisches Array
 
OMG, ja ich seh's!

Hab die Zeile gleich mal zu
Delphi-Quellcode:
setLength(KartenArray, laenge+1)
geändert, allerdings sagt er mir jetzt in dieser Zeile Inkompatible Typen.
Aber das ist seltsam, ich übergebe A an diese Procedure und A ist vom Typ "array of TKarte" und KartenArray auch..

Kann es sein das die lokale Arrayvariable nicht als dynamisch anerkannt wird? Wenn ja, wie kann ich das umgehen?

mkinzler 2. Sep 2010 14:37

AW: Dynamisches Array
 
Ob das Selbe dahintersteckt ist dem Compiler egal, der Typ(name) muss gleich sein

Lotus 2. Sep 2010 14:42

AW: Dynamisches Array
 
Aber ist er doch oder nicht?

Delphi-Quellcode:
procedure cardToArray(karte:TKarte; KartenArray:array of TKarte);
var laenge:integer;
begin
laenge:=length(KartenArray);
setLength(KartenArray, laenge+1);
KartenArray[laenge]:=karte;
end;

mkinzler 2. Sep 2010 14:44

AW: Dynamisches Array
 
Deklareiere dir einen Typ dafür

Delphi-Quellcode:
TKartenAaray = Array of TKarte;

Lotus 2. Sep 2010 14:51

AW: Dynamisches Array
 
Jetzt meckert er zwar nicht mehr rum, dafür erhöht er aber auch nicht die Länge des Arrays!

Delphi-Quellcode:
type TKartenArray = Array of TKarte;

var
KartenGezogen : TKartenArray;

implementation

procedure cardToArray(karte:TKarte; KartenArray:TKartenArray);
var laenge:integer;
begin
laenge:=length(KartenArray);
setLength(KartenArray, laenge+1);
KartenArray[laenge]:=karte;
end;

DeddyH 2. Sep 2010 14:59

AW: Dynamisches Array
 
Wenn Du sowieso das Array als globale Variable deklariert hast, wozu dann der Parameter? Und wenn das einen Grund hat, versuch es mal mit einem var-Parameter.

Lotus 2. Sep 2010 15:08

AW: Dynamisches Array
 
Es sollen später noch mehr Array's dazukommen, die auch alle mit dieser Procedure funktionieren sollen, von daher der Parameter ;)

Bei nem var-Parameter kollidiere ich dann wieder mit Inkompatible Typen.. ich stell mich gerade doof an glaube ich :-/

Ich bin sogar schon auf die Fehlermeldung gekommen:
[Fehler] Unit1.pas(274): Inkompatible Typen: 'Array' und 'dynamic array'

DeddyH 2. Sep 2010 15:36

AW: Dynamisches Array
 
Das funktioniert nicht?
Delphi-Quellcode:
type TKartenArray = Array of TKarte;

var
KartenGezogen : TKartenArray;

implementation

procedure cardToArray(karte:TKarte; var KartenArray:TKartenArray);
var laenge:integer;
begin
  laenge:=length(KartenArray);
  setLength(KartenArray, laenge+1);
  KartenArray[laenge]:=karte;
end;

Luckie 2. Sep 2010 15:42

AW: Dynamisches Array
 
Warum dieser Umstand und dieses halbherzige OOP? Warum nimmst du keine TObjectList? Damit ersparst du dir das ganze.

Lotus 2. Sep 2010 16:18

AW: Dynamisches Array
 
@Detlef
Compilieren tut er es, aber die Laenge des Arrays bleibt seltsamerweise auf 0.. warum?

Das mit der Objectlist werde ich mal ausprobieren... ich scheu mich vor neuen Sachen ein bisschen *shy*

DeddyH 2. Sep 2010 16:40

AW: Dynamisches Array
 
Woher soll ich denn wissen, warum? Wie rufst Du die Prozedur denn auf?

Lotus 2. Sep 2010 16:50

AW: Dynamisches Array
 
Delphi-Quellcode:
cardToArray(karte,KartenGezogen);
und KartenGezogen ist vom Typ TKartenArray

DeddyH 2. Sep 2010 16:57

AW: Dynamisches Array
 
Bist Du einmal mit dem Debugger durchgesteppt? Wird die Prozedur auch wirklich durchlaufen?

Lotus 2. Sep 2010 17:01

AW: Dynamisches Array
 
Ich hab ne Showmessage in der Procedure drin (steht in dem Forumpost hier nicht drin) und diese gibt mir die Länge an

Delphi-Quellcode:
laenge:=length(KartenArray);
showmessage(inttostr(laenge));
Da das ganze 6x aufgerufen wird, bin ich sicher das die Procedure durchlaufen wird ;-)
Debugger wird also nichts finden..

Ich wollte das jetzt mal mit der TObjectlist machen.. aber ich hab noch recht wenig Erfahrung mit OOP.. die Liste createn hab ich ja geschafft, aber wenn ich jetzt was dazufügen will, brauch ich ja nen Object! Wie mache ich jetzt aus meiner TKarte ein Objekt? Oder anders gefragt, wie füge ich die TKarte in die ObjectList?

DeddyH 2. Sep 2010 17:19

AW: Dynamisches Array
 
Du musst in Zeile 43 aus record class machen :glaskugel:

Lotus 2. Sep 2010 17:25

AW: Dynamisches Array
 
Zeile 42 passte diesmal nicht ganz :-P

Allerdings funktioniert dann die "with .. do" funktion nichtmehr oder? Das wäre ziemlich tödlich :X

hugo1990 2. Sep 2010 18:12

AW: Dynamisches Array
 
Also with ... do tut auch mit Objekten, aber das hättest du auch durch probieren rausfinden können.
und wenn du aus record einfach class machst, dann sollte sich an deinem Code mit dem with ... do auch nichts ändern.

[OT]
Eigentlich Schade, dass ein so schönes Programmierkonstrukt wie with ... do in kaum einer anderen Sprache existiert.
[/OT]

mkinzler 2. Sep 2010 18:14

AW: Dynamisches Array
 
Es ist aber auch eines der gefährlichsten Konstrukte

Lotus 2. Sep 2010 18:16

AW: Dynamisches Array
 
Ich HABS ausporbiert... und es kam ein Fehler deswegen fragte ich ja.

Zugriffsverletzung auf Speicher kam dann..

Delphi-Quellcode:
type
  TKarte = class
            KartenName : string[12]; //Sieben, Acht, Neun, Zehn, Bube, Dame, König, Ass
            KartenWert : Byte; //zur Bestimmung des Indexes beim Array
            KartenZiffer : Byte; //Zur Namens - Bildauflösung B=11, D=12 K=13 Ass=1
            KartenTyp : Byte; //Karo (1), Herz(2), Pik(3), Kreuz(4)
            end;

with Karte do begin
KartenName:= 'Karo Zwei';
KartenWert:=1;
KartenTyp:=1;
KartenZiffer:=2;
end;
Mit Record klappts übrigens wunderbar (zumindestens das with do)

DeddyH 2. Sep 2010 18:18

AW: Dynamisches Array
 
Klassen (besser gesagt: Klasseninstanzen) muss man ja auch erst erzeugen.

Lotus 2. Sep 2010 18:22

AW: Dynamisches Array
 
Das heißt ich muss nur einmal Karte.create aufrufen?

mkinzler 2. Sep 2010 18:26

AW: Dynamisches Array
 
Nein
Delphi-Quellcode:
Karte := TKarte.Create;

DeddyH 2. Sep 2010 18:26

AW: Dynamisches Array
 
Einmal für jede Karte, die Du der Liste hinzufügen willst, ja.

Lotus 2. Sep 2010 18:28

AW: Dynamisches Array
 
Hey danke! Das klappt.. das werd ich jetzt mal probieren!

@DeddyH

Ich benutz immer dieselbe Variable "Karte".. also ich überschreib nur die Werte dieser.. von daher also nur einmal create :)

DeddyH 2. Sep 2010 18:29

AW: Dynamisches Array
 
Wenn es nur eine Karte ist, wozu dann das Array/die Liste?

Lotus 2. Sep 2010 18:36

AW: Dynamisches Array
 
Es ist nicht nur eine Karte oO? Ich benutzte nur die eine Variable für alle Karten.. bei 52 Karten müsste ich ja sonst 52x Karte anlegen..

Ich hab jetzt mal probeweise zu der Objectlist 2 karten hinzugefügt.. hat auch geklappt
Delphi-Quellcode:
 ObjectList.Add(Player[i].HandKarte[1]);
    ObjectList.Add(Player[i].HandKarte[2]);
Aber nachdem ich das Programm geschlossen habe, kommt nen Fehler

Delphi-Quellcode:
procedure TForm1.FormDestroy(Sender: TObject);
begin
ObjectList.free;
end;
Zugriffsverletzung bei der Adresse 000000000 ... ich dachte das Freigeben muss man machen?

DeddyH 2. Sep 2010 18:41

AW: Dynamisches Array
 
Stepp doch einfach mal durch und schau, wann der Fehler auftritt. Wir kennen ja nur Bruchteile des Codes, was sollen wir denn sagen?

Lotus 2. Sep 2010 18:44

AW: Dynamisches Array
 
Der Fehler tritt nur auf, wenn ich das Programm schließe, also IN der Destroy.. weiterhin setzt mir Delphi auch den Curser in die FormDestroy, also sollte auch dort der Fehler sein oder nicht?

Edit:
Kommentiere ich die Zeile Objectlist.free aus, dann kommt der Fehler auch nicht

alzaimar 2. Sep 2010 18:48

AW: Dynamisches Array
 
Ich tipp mal darauf, das in der Objektliste schon freigegebene Instanzen sind.

Beim Freigeben der Objektliste werden die in der Liste befindlichen Objekte nochmals freigegeben, sofern die Eigenschaft 'OwnsObjects' auf True gesetz ist.

DeddyH 2. Sep 2010 18:50

AW: Dynamisches Array
 
Das finde ich jetzt etwas merkwürdig, aber meinetwegen.

Lotus 2. Sep 2010 18:55

AW: Dynamisches Array
 
Ah, das bedeutet ich muss sie also nicht mehr freigeben? Sehr gut :)

Das mit dem Array hab ich jetzt schon ein wenig genauer lokalisieren können..
Mein jetziges Problem ist "glaube" ich, dass die Procedure irgendwie nur Call by Value ist...?!?

Ich hab jetzt mal fix nen ganz billiges Beispiel gemacht:

Delphi-Quellcode:
unit test;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    procedure FormCreate(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;
  myArray : array[0..3] of integer;

implementation

{$R *.dfm}

procedure fill_array(ta:array of integer; wert:integer);
var i:integer;
begin
for i:=low(ta) to high(ta) do
ta[i]:=wert;
end;

procedure TForm1.FormCreate(Sender: TObject);
var i:integer;
begin
fill_array(myArray,2);
for i:=low(myarray) to high(myarray) do
Form1.Memo1.Text:=Form1.Memo1.Text+ ' ' +(inttostr(myArray[i]));
end;

end.
In der Memo1 steht dann 4x 0! Und keine 2.. Wie kann man das umgehen? Global "kann" ich nicht auf das Array zugreifen, die ich die procedure ja für mehrere Arrays benutzen möchte, sonst müsste ich ja immer wieder eine neue procedure schreiben für jedes array

rapante 2. Sep 2010 19:23

AW: Dynamisches Array
 
versuchs mal so, dann ersparst du dir auch die globale Variable...
Delphi-Quellcode:
unit test;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TMyArray = array[0..3] of integer;

  TForm1 = class(TForm)
    Memo1: TMemo;
    procedure FormCreate(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure fill_array(var ta: TMyArray; wert:integer);
var i:integer;
begin
for i:=low(ta) to high(ta) do
ta[i]:=wert;
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  i:integer;
  MyArray: TMyArray;
begin
fill_array( myArray,2);
for i:=low(myarray) to high(myarray) do
Form1.Memo1.Text:=Form1.Memo1.Text+ ' ' +(inttostr(myArray[i]));
end;

end.

Lotus 2. Sep 2010 21:39

AW: Dynamisches Array
 
Ja das klappt, aber wieso klappt das nicht bei meinem richtigen Projekt? Ich habs genau so!

Ich versuch jetzt mal die nötigen Infos zu posten:

Delphi-Quellcode:
type
TKarte = record
            KartenName : string[12]; //Sieben, Acht, Neun, Zehn, Bube, Dame, König, Ass
            KartenWert : Byte; //zur Bestimmung des Indexes beim Array
            KartenZiffer : Byte; //Zur Namens - Bildauflösung B=11, D=12 K=13 Ass=1
            KartenTyp : Byte; //Karo (1), Herz(2), Pik(3), Kreuz(4)
            end;

TKartenArray = array[0..6] of TKarte;

var KartenGezogen : TKartenArray;


procedure cardToArray(karte:TKarte; TKA:TKartenArray; laenge:integer);
begin
TKA[laenge]:=karte;
end;

procedure CardToPlayer();
var i,zahl : byte;
begin
for i:=low(Player) to players-1 do begin
  cardToArray(Player[i].HandKarte[1],KartenGezogen,0);
  cardToArray(Player[i].HandKarte[2],KartenGezogen,1);
  end;
Form1.Memo1.Text:=KartenGezogen[0].KartenName;
end;


procedure TForm1.FormCreate(Sender: TObject);
begin
CardToPlayer();
end;
So, mein Problem ist, er übergibt in der procedure cardToArray "korrekt" die Karte an TKA, allerdings ist sie danach trotzdem NICHT in dem Array KartenGezogen ... was man anhand der memo1 nachvollziehn kann.. Das ist exakt dasselbe Schema wie bei dem Array, wo wir das mit der 2 gefüllt haben, nur etwas komplexer.. ich versteh's nicht warum der das nicht in das Array schreibt.


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:07 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