Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi denkfehler; array-> dynarray (https://www.delphipraxis.net/127138-denkfehler%3B-array-dynarray.html)

vsilverlord 8. Jan 2009 10:33


denkfehler; array-> dynarray
 
Hallo,
ich hab ein etwas größeres Projekt, weswegen ich nicht den ganzen quelltext reinschreiben kann.
Ich werde mal versuchen zu beschreiben. Vorher hatte ich einen statischen array mit seiner anzahl als record:
Delphi-Quellcode:
tviechergruppe=record
viecher:array[0..10000] of tviech;
viecheranzahl:integer;
end;
tviech ist einfach ein weiterer record mit den eigenschaften des viechs.
wenn ich also die anzahl der viecher erhöhen wollte, hab ich nur die viecheranzahl erhöht. Ein neues viech füge ich dann so hinzu:
Delphi-Quellcode:
var
blaueviecher:tviechergruppe;
...
inc(blaueviecher.viecheranzahl);
blaueviecher.viecher[blaueviecher.viecheranzahl]:=blaueviecher.viecher[blaueviecher.viecheranzahl-1] // hier sieht es so aus wie das letzte
mutiere(blaueviecher.viecher[blaueviecher.viecheranzahl]) // hier wird es ein inviduum, da es mutiert
(alles hat perfekt funktioniert)
Nun wollte ich das ganze mit einem dynamischen array machen, um speicher zu sparen:
Delphi-Quellcode:
tviechergruppe=record
viecher:array of tviecher;
viecheranzahl: integer
zugreifen wollte ich dann so:
Delphi-Quellcode:
var
blaueviecher:tviechergruppe;
...
inc(blaueviecher.viecheranzahl);
setlength(blaueviecher.viecher,blaueviecher.viecheranzahl+1); //der array ist 1 größer wie die benötigte anzahl
blaueviecher.viecher[blaueviecher.viecheranzahl]:=blaueviecher.viecher[blaueviecher.viecheranzahl-1] // hier sieht es so aus wie das letzte
mutiere(blaueviecher.viecher[blaueviecher.viecheranzahl]) // hier wird es ein inviduum, da es mutiert
jetzt taucht das phänomen auf, dass ALLE viecher so aussehen wie das letzte. Ich kann mir nicht im geringsten vorstellen warum das so sein sollte. Ich such jetzt schon stunden den fehler. für mich sieht das so aus, als ob das ein delphi-fehler oder irgendein abstruser systemfehler ist.

SirThornberry 8. Jan 2009 10:40

Re: denkfehler; array-> dynarray
 
nur durch Umstellung des Arrays? Schalte einfach mal die Bereichtsprüfung ein. Vielleicht schreibst du ja auch irgendwo drüber hinaus.

vsilverlord 8. Jan 2009 10:46

Re: denkfehler; array-> dynarray
 
Es kommt keine Fehlermeldung, es ist einfach nur so, dass alle viecher so sind wie das letzte viech.

Klaus01 8. Jan 2009 10:55

Re: denkfehler; array-> dynarray
 
.. machst Du nicht mit dieser Zeile alle Elemete gleich?

Delphi-Quellcode:
blaueviecher.viecher[blaueviecher.viecheranzahl]:=blaueviecher.viecher[blaueviecher.viecheranzahl-1]
Angenommen viecherAnzahl = 8
Dann bekommt das Element 8 alle Datenfelder des Elementes 7
Angenommen viecherAnzahl = 9
Dann bekommt das Element 9 alle Datenfelder des Elementes 8

Nun sind schon die Element 7,8 und 9 gleich.

Nur merkwürdig, dass das ganze vorher korrekt gelaufen ist?

Grüße
Klaus

vsilverlord 8. Jan 2009 11:03

Re: denkfehler; array-> dynarray
 
ähm... möglicherweise hast du recht, aber stumpfsinnigerweise hat es vorher funktioniert. Außerdem will ich ja nur das allerletzte viech so werden lassen das allervorletze viech. Gibts da eine bessere Lösung=? [hoffnung keimt auf]

Klaus01 8. Jan 2009 11:09

Re: denkfehler; array-> dynarray
 
.. kanst Du dazu etwas mehr Code zeigen?

Hier sieht man ja nicht einmal, ob das ganze in einer Schleife läuft
oder in welcher Umgebung das ganze stattfindet.

Grüße
Klaus

vsilverlord 8. Jan 2009 11:22

Re: denkfehler; array-> dynarray
 
da ist nur ein timer, der damit zusammen hängt:
Delphi-Quellcode:
procedure tform1.timer1timer(sender:tobject);
begin
inc(blaueviecher.viecheranzahl);
setlength(blaueviecher.viecher,blaueviecher.viecheranzahl+1); //der array ist 1 größer wie die benötigte anzahl
blaueviecher.viecher[blaueviecher.viecheranzahl]:=blaueviecher.viecher[blaueviecher.viecheranzahl-1] // hier sieht es so aus wie das letzte
mutiere(blaueviecher.viecher[blaueviecher.viecheranzahl]) // hier wird es ein inviduum, da es mutiert
end
das ist ja der witz an der sache. Das ist praktisch das wesentliche, der rest sind sachen die damit nicht zusammenhängen (labels, buttons, usw);

Klaus01 8. Jan 2009 11:29

Re: denkfehler; array-> dynarray
 
.. im Prinzip kann man ja einen Timer bzw. dessen Funktion wie eine Schleife
sehen.

Und dann wird dieser Code immer wieder ausgeführt.

Delphi-Quellcode:
procedure tform1.timer1timer(sender:tobject);
begin
  inc(blaueviecher.viecheranzahl);
  setlength(blaueviecher.viecher,blaueviecher.viecheranzahl+1); //der array ist 1 größer wie die benötigte anzahl
  blaueviecher.viecher[blaueviecher.viecheranzahl]:=blaueviecher.viecher[blaueviecher.viecheranzahl-1] // hier sieht es so aus wie das letzte
  mutiere(blaueviecher.viecher[blaueviecher.viecheranzahl]) // hier wird es ein inviduum, da es mutiert
end
hm, wenn ich es mir recht überlege sollte es doch funktionieren:

Wenn mutiere etwas an den Daten des letzten Arrayfeldes ändert hat beim nächsten Durchlauf
das zweitletzte Element die gleichen Daten.
Die neue letzte wird dann wieder mutiert.

Kannst Du mal die Prozedur mutiere hier anfügen,
kann es sein das die Daten nicht richtig in das Array zurückgeschrieben werden.
Denn ein dyn.Array ist nur ein Pointer wenn Du es als Parameter an eine Prozedur übergibst.

[edit], das kann es eigentlich auch nicht sein, denn es wird ja ein tviech übergeben.
Bin mit meinem Latein am Ende.

[edit2] hast Du den Paramter in der mutiere Prozedur als var Parameter deklariert?

Grüße
Klaus

HenKst 8. Jan 2009 11:43

Re: denkfehler; array-> dynarray
 
Also wie Klaus schon sagte

eigentlich müssten immer schon alle Elemente identisch gewesen sein weil du mit
Delphi-Quellcode:
blaueviecher.viecher[blaueviecher.viecheranzahl]:=blaueviecher.viecher[blaueviecher.viecheranzahl-1];
immer nur die Pointer kopierst

Wenn du bei einem eine property änderst, änderst du sie in allen.
Warum das mit nem Statischen array klappt versteh ich nicht.

Richtigerweise müsstest du dir für TViech eine assign methode schreiben.
Dann per
Delphi-Quellcode:
blaueviecher.viecher[blaueviecher.viecheranzahl]:= TViech.Create;
blaueviecher.viecher[blaueviecher.viecheranzahl].Assign(blaueviecher.viecher[blaueviecher.viecheranzahl-1]);
das TViech "kopieren".
Dann hast du eine individuelle isntanz die du ändern kannst ohne das sich das auf die anderen auswirkt.

GreeZ HenKst

Klaus01 8. Jan 2009 11:49

Re: denkfehler; array-> dynarray
 
@HenKst

das Assign muss nicht sein, denn die Array Elemente sind ja "nur" records als statisch.
Das Array an sich ist dynamisch die einzelnen Felder wiederum statisch.

@vsilverlord
Ich denke es liegt ein Fehler in der Procedure mutiere vor,
denn nur wenn hier das Array Feld (Tviech) nicht geändert wird
sind alle Elemente/Felder des Arrays gleich.

Grüße
Klaus

nahpets 8. Jan 2009 11:51

Re: denkfehler; array-> dynarray
 
Hallo,

ohne jetzt voreilig sein zu wollen, aber liegt der Fehler nicht in der 5. Zeile?

Delphi-Quellcode:
procedure tform1.timer1timer(sender:tobject);
begin
  inc(blaueviecher.viecheranzahl);
  setlength(blaueviecher.viecher,blaueviecher.viecheranzahl+1); //der array ist 1 größer wie die benötigte anzahl
  blaueviecher.viecher[blaueviecher.viecheranzahl]:=blaueviecher.viecher[blaueviecher.viecheranzahl-1] // hier sieht es so aus wie das letzte
  mutiere(blaueviecher.viecher[blaueviecher.viecheranzahl]) // hier wird es ein inviduum, da es mutiert
end
muss dass nicht
Delphi-Quellcode:
  blaueviecher.viecher[blaueviecher.viecheranzahl]:=blaueviecher.viecher[blaueviecher.viecheranzahl] // hier sieht es so aus wie das letzte
heißen.
Am Beginn der Procedure befindet sich das letzte Viech im letzten Eintrag des Array. Das Array wird um einen Eintrag vergrößert. Nun ist das ursprünglich letzte Viech im vorletzten Eintrag des Arrays. Wenn die Größe des Arrays blaueviecher.viecheranzahl + 1 ist, müsste das letzte Viech doch in blaueviecher.viecheranzahl stehen und nicht in blaueviecher.viecheranzahl - 1. Oder täusche ich mich da jetzt?

vsilverlord 8. Jan 2009 12:00

Re: denkfehler; array-> dynarray
 
ich bin mit meinem latein auch am ende. der fehler ist so verrückt, ich glaube ich bekomm gleich en krampf im hirn.
das ergebnis ist das, dass ALLE so sind wie das letzte, mutierte viech.
Dieses viech ist nachweißlich anders als die anderen. Ich hab hier ein paar zahlenbeispiele:
viech1:
länge:1
haare:2
-- neuer timer durchgang
viech1:
länge:3
haare:5
viech2:
länge:3
haare:5
-- neuer timer durchgang
viech1:
länge:8
haare:1
viech2:
länge:8
haare:1
viech3:
länge:8
haare:1
So. Was sagt man dazu? der fehler muss in der zuweisung des arrays liegen, warum auch immer.
so sollte übrigens das ergebnis aussehen (nach 2 timer durchgängen):
viech1:
länge:1
haare:2
viech2:
länge:3
haare:5
viech3:
länge:8
haare:1

:pale:
@nahpets: ohne jetzt anmaßend klingend zu wollen, aber dann wäre der ganze array leer.
blaueviecher.viecher[blaueviecher.viecheranzahl]:=blaueviecher.viecher[blaueviecher.viecheranzahl]
ist das gleiche wie: 0:=0
das ist so, weil vorher die anzahl erhöht wird. [oder liege ich falsch?]

HenKst 8. Jan 2009 12:00

Re: denkfehler; array-> dynarray
 
Zitat:

Zitat von Klaus01
@HenKst

das Assign muss nicht sein, denn die Array Elemente sind ja "nur" records als statisch.
Das Array an sich ist dynamisch die einzelnen Felder wiederum statisch.

Achso ich hatte überlesen das TViech ein record ist :shock:

Dann schliesse ich mich dir mal an und hätte gerne mal den mutiercode gesehn ;)

@stephan
zu dem Zeitpunkt hat das array viecherzahl+1 viele Elemente
in [viecherzahl] steht also das letzte und := [viecherzahl-1] kopiert das vorletzte
Soweit ich das verstanden habe ist das genau was er will.

vsilverlord 8. Jan 2009 12:07

Re: denkfehler; array-> dynarray
 
ach ja, die funktion mutiere hat ja nur den parameter tviech: [vereinfacht, aber im prinzip das gleiche]
Delphi-Quellcode:
procedure mutiere(viech:tviech):tviech;
begin
result.länge:=viech.länge+random(5);
result.haare:=viech.haare+random(5);
end;

vsilverlord 8. Jan 2009 12:09

Re: denkfehler; array-> dynarray
 
vllt hängt das problem auch irgendwie mit setlength und dem array zusammen.
vllt kann ich aus dem tviech ein object bauen und es dann in eine tobjetlist stecken.[wobei das ergebnis theoretisch dasselbe sein sollte]

HenKst 8. Jan 2009 12:13

Re: denkfehler; array-> dynarray
 
Delphi-Quellcode:
mutiere(blaueviecher.viecher[blaueviecher.viecheranzahl])
Delphi-Quellcode:
procedure mutiere(viech:tviech):tviech;
begin
result.länge:=viech.länge+random(5);
result.haare:=viech.haare+random(5);
end;
erm... procedure|result?

aber fällt dir was auf?^^

Du änderst nur das result, weisst dieses aber nicht zu.

Wobei ich immernoch nicht verstehe wie das mit nem statischen array funktioniert haben soll.

Uwe Raabe 8. Jan 2009 12:16

Re: denkfehler; array-> dynarray
 
Zitat:

Zitat von vsilverlord
ach ja, die funktion mutiere hat ja nur den parameter tviech: [vereinfacht, aber im prinzip das gleiche]
Delphi-Quellcode:
procedure mutiere(viech:tviech):tviech;
begin
result.länge:=viech.länge+random(5);
result.haare:=viech.haare+random(5);
end;

Jetzt hast du aber gemogelt: eine procedure hat normalerweise keinen Rückgabewert!

nahpets 8. Jan 2009 12:19

Re: denkfehler; array-> dynarray
 
Hallo,
kann sein, dass ich vollkommen daneben liege: (bitte nicht hauen :wink:)

Gehen wir davon aus, dass vor dem ersten Timerausruf blaueviecher.viecheranzahl = 0 sei.

Delphi-Quellcode:
procedure tform1.timer1timer(sender:tobject);
begin
  inc(blaueviecher.viecheranzahl); // = 1
  setlength(blaueviecher.viecher,blaueviecher.viecheranzahl+1); // Array hat 2 Elemente
  [blaueviecher.viecheranzahl]:=blaueviecher.viecher[blaueviecher.viecheranzahl-1] // das 0. Element
  mutiere(blaueviecher.viecher[blaueviecher.viecheranzahl]) // Das erste Element enthält das mutierte 0. Element.
end
Was passiert hier mit dem zweiten Viech, bleibt das leer?

Andererseits: Wenn nach einer Mutation alle gleich sind, dann könnte HenKst mit seiner Pointer-Vermutung ja durchaus doch recht haben. Auch, das ist doch irgendwie komisch.

Klaus01 8. Jan 2009 12:20

Re: denkfehler; array-> dynarray
 
Zitat:

Zitat von vsilverlord
ach ja, die funktion mutiere hat ja nur den parameter tviech: [vereinfacht, aber im prinzip das gleiche]
Delphi-Quellcode:
procedure mutiere(var viech:tviech);
begin
  result.länge:=viech.länge+random(5);
  result.haare:=viech.haare+random(5);
end;

So ^ sollte es gehen.

Grüße
Klaus

HenKst 8. Jan 2009 12:24

Re: denkfehler; array-> dynarray
 
Zitat:

Zitat von Klaus01
Zitat:

Zitat von vsilverlord
ach ja, die funktion mutiere hat ja nur den parameter tviech: [vereinfacht, aber im prinzip das gleiche]
Delphi-Quellcode:
procedure mutiere(var viech:tviech);
begin
  result.länge:=viech.länge+random(5);
  result.haare:=viech.haare+random(5);
end;

So ^ sollte es gehen.

Grüße
Klaus

Ändert doch immernoch nichts am übergebenen TViech.
Oder ist result in procedure ein pseudonym für den ersten var parameter? (könnte ja sein :) )
Delphi-Quellcode:
procedure mutiere(var viech:tviech);
begin
  viech.länge:=viech.länge+random(5); //oder inc(viech.länge, random(5) wenns kurz sein soll:)
  viech.haare:=viech.haare+random(5);
end;
sollte klappen

oder hallte tatsächlich

Delphi-Quellcode:
Function mutiere(var viech:tviech): TViech
begin
  result.länge:=viech.länge+random(5);
  result.haare:=viech.haare+random(5);
end;

blaueviecher.viecher[blaueviecher.viecheranzahl]:= mutiere(blaueviecher.viecher[blaueviecher.viecheranzahl]);
dann könnte man auch neue viecher direkt als mutationen von alten viechern erzeugen.

Uwe Raabe 8. Jan 2009 12:25

Re: denkfehler; array-> dynarray
 
Zitat:

Zitat von Klaus01
Zitat:

Zitat von vsilverlord
ach ja, die funktion mutiere hat ja nur den parameter tviech: [vereinfacht, aber im prinzip das gleiche]
Delphi-Quellcode:
procedure mutiere(var viech:tviech);
begin
  result.länge:=viech.länge+random(5);
  result.haare:=viech.haare+random(5);
end;

So ^ sollte es gehen.

Jetzt kennt der Compiler aber kein "result"!

Ich gebe mal zu bedenken: wenn du uns hier "bereinigten" Code zeigst, kann es sein, daß du den Fehler "wegbereinigst".

Klaus01 8. Jan 2009 12:31

Re: denkfehler; array-> dynarray
 
Zitat:

Zitat von Uwe Raabe
Zitat:

Zitat von Klaus01
Zitat:

Zitat von vsilverlord
ach ja, die funktion mutiere hat ja nur den parameter tviech: [vereinfacht, aber im prinzip das gleiche]
Delphi-Quellcode:
procedure mutiere(var viech:tviech);
begin
  result.länge:=viech.länge+random(5);
  result.haare:=viech.haare+random(5);
end;

So ^ sollte es gehen.

Jetzt kennt der Compiler aber kein "result"!

Ich gebe mal zu bedenken: wenn du uns hier "bereinigten" Code zeigst, kann es sein, daß du den Fehler "wegbereinigst".

Das kommt davon, copy und paste, und nicht darauf achten was denn kopiert wurde:

Delphi-Quellcode:
procedure mutiere(var viech:tviech);
begin
  viech.länge+random(5);
  viech.haare+random(5);
end;

HenKst 8. Jan 2009 12:34

Re: denkfehler; array-> dynarray
 
Zitat:

Zitat von Klaus01

Delphi-Quellcode:
procedure mutiere(var viech:tviech);
begin
  viech.länge+random(5);
  viech.haare+random(5);
end;

örm, erzeugt das überhaupt code?
Da fehlt ne Zuweisung oder?

Wir sind nicht in C und haben soweit ich weiss keinen += operator :D

...warum funktionieren bei meinen delphicodes die highlights nich...

Klaus01 8. Jan 2009 12:38

Re: denkfehler; array-> dynarray
 
Zitat:

Zitat von HenKst
Zitat:

Zitat von Klaus01

Delphi-Quellcode:
procedure mutiere(var viech:tviech);
begin
  viech.länge+random(5);
  viech.haare+random(5);
end;

örm, erzeugt das überhaupt code?
Da fehlt ne Zuweisung oder?

Wir sind nicht in C und haben soweit ich weiss keinen += operator :D

...warum funktionieren bei meinen delphicodes die highlights nich...

ich sollte nach Hause gehen, bin sowas von daneben heute...

Delphi-Quellcode:
procedure mutiere(var viech:tviech);
begin
  viech.laenge:=viech.laenge+random(5);
  viech.haare:=viech.haare+random(5);
end;
und mein Delphi mag auch keine Umlaute.

Danke und Grüße
Klaus

vsilverlord 8. Jan 2009 12:47

Re: denkfehler; array-> dynarray
 
Zitat:

Delphi-Quellcode:
blaueviecher.viecher[blaueviecher.viecheranzahl]:= mutiere(blaueviecher.viecher[blaueviecher.viecheranzahl]);

Tut mir leid, ich habs falsch geschrieben. So wie oben sieht es aus.
Leider ist das gar nicht das Problem, es besteht immer noch. Das problem bei dem array war sowieso, dass er maximal 10000 viecher aufnehmen konnte. Wieviel viecher kann ich mit tobjectlist aufnehmen? Ich brauch es ja erst gar nicht versuchen, wenn da weniger reinpassen. Kann es sein, dass setlength alle vorhandenen felder um eins nach vorne verschiebt, sodass das feld 0 frei wird? so könnte ich mir vorstellen, dass das problem entsteht. [wäre aber trotzdem nicht logisch]
Gib es noch andere Mengentypen, die Sinn machen?
grüße, hoffnungslos frustriert

HenKst 8. Jan 2009 13:15

Re: denkfehler; array-> dynarray
 
Zitat:

Zitat von vsilverlord
viech1:
länge:1
haare:2
-- neuer timer durchgang
viech1:
länge:3
haare:5
viech2:
länge:3
haare:5
-- neuer timer durchgang
viech1:
länge:8
haare:1
viech2:
länge:8
haare:1
viech3:
länge:8
haare:1

huch den hab ich ja noch garnich gesehn^^


hmm das wäre genau was passiert wenn du nur pointer durch die Gegend schieben würdest...

Sicher das TViech ein record ist?:D

hab mir auch grade ein testprojekt gebaut und deinen code kopiert.
TViech als
record mit laenge und haare als integer declariert

funktioniert roblemlos(abgesehen davon das inc(viecheranzahl) und setlengh mit viecheranzahl+1 beim ersten durchlauf 2 elemente kreiert aber das hab ich vermutlich falsch initialisiert)...

nahpets 8. Jan 2009 13:24

Re: denkfehler; array-> dynarray
 
Zitat:

Zitat von HenKst
funktioniert roblemlos(abgesehen davon das inc(viecheranzahl) und setlengh mit viecheranzahl+1 beim ersten durchlauf 2 elemente kreiert aber das hab ich vermutlich falsch initialisiert)...

ne, dass ist genau das, wo ich eine mögliche Fehlerursache vermute, aber Deine Pointertheorie ist nicht von der Hand zu weisen.

@vsilverlord
gib' mal den Inhalt des Arrays vor und nach dem SetLength aus, dann müsstest Du doch sehen können, ob da verstrubbelt wird und wenn Du dann diese beiden Ausgaben neben die nach der Mutation legst, müsstest Du sehen können, wann der Inhalt durcheinanderkommt, bzw. hier ja unerwartet vereinheitlicht wird.

HenKst 8. Jan 2009 13:32

Re: denkfehler; array-> dynarray
 
Ich hab jetzt als Initialisierung setlength mit 1 gemacht aber die viecheranzahl auf 0 gelassen, damit funktionierts wunderprächtig

Delphi-Quellcode:
  TViech = record
    laenge: integer;
    haare: integer;
  end;

  TViecherGruppe = record
    viecheranzahl: integer;
    viecher: array of TViech;
  end;
var
  Form2: TForm2;
  blaueviecher: TViecherGruppe;

implementation

{$R *.dfm}

Function mutiere(var viech:tviech): TViech;
begin
  result.laenge:=viech.laenge+random(5);
  result.haare:=viech.haare+random(5);
end;

procedure TForm2.Button1Click(Sender: TObject);
var
  i: integer;
begin
  blaueviecher.viecheranzahl:= 0;
  for i := 0 to 10000 do begin
    inc(blaueviecher.viecheranzahl);
    setlength(blaueviecher.viecher,blaueviecher.viecheranzahl+1); //der array ist 1 größer !!!ALS!!!^^ die benötigte anzahl
    blaueviecher.viecher[blaueviecher.viecheranzahl]:=
    blaueviecher.viecher[blaueviecher.viecheranzahl-1]; // hier sieht es so aus wie das letzte
    blaueviecher.viecher[blaueviecher.viecheranzahl]:=
    mutiere(blaueviecher.viecher[blaueviecher.viecheranzahl]) // hier wird es ein inviduum, da es mutiert
  end;
end;

procedure TForm2.FormCreate(Sender: TObject);
begin
  randomize;
  blaueviecher.viecheranzahl:= 0;
  setlength(blaueviecher.viecher, 1);
  blaueviecher.viecher[0].haare:= 0;
  blaueviecher.viecher[0].laenge:= 1;
end;

vsilverlord 8. Jan 2009 13:35

Re: denkfehler; array-> dynarray
 
Ich hab mir das jetzt noch einmal mit test-echos durchgeschaut, und ihr hattet irgendwie recht.
in
Delphi-Quellcode:
blaueviecher.viecher[blaueviecher.viecheranzahl]:= mutiere(blaueviecher.viecher[blaueviecher.viecheranzahl]);
geht er Alle felder des arrays durch und mutiert alle gleichzeitig. Bloß warum??? Wie kann ich das machen, dass er nur das eine, letzte Feld mutiert?

Bomberbb 8. Jan 2009 13:35

Re: denkfehler; array-> dynarray
 
Also, mal ein kleines Prog draus gemacht, dass funzt:
Delphi-Quellcode:
Program Project1;
Uses sysutils;
Type
  tviech = Record
    laenge: Real;
    haare: Real;
  End;

  tblaueviecher = Record
    Viecher: Array of tviech;
  End;

Var
  blaueviecher: tblaueviecher;
  i: integer;

Procedure mutiere(Var viech: tviech);
Begin
  viech.laenge := viech.laenge + random(5);
  viech.haare := viech.haare + random(5);
End;
Begin
  Randomize;
  For i := 1 To 3 Do
  Begin
    setlength(blaueviecher.viecher, succ(length(blaueviecher.viecher))); //der array ist 1 größer wie die benötigte anzahl
    If length(blaueviecher.viecher) > 1 Then
      blaueviecher.viecher[high(blaueviecher.viecher)] := blaueviecher.viecher[high(blaueviecher.viecher)-1]; // hier sieht es so aus wie das letzte
    mutiere(blaueviecher.viecher[high(blaueviecher.viecher)]) // hier wird es ein inviduum, da es mutiert
  End;
End.
Ergebnisse nach dem Durchlauf:
blaueviecher.viecher[high(blaueviecher.viecher)]: (laenge:5; haare:3)
blaueviecher.viecher: ((laenge:0; haare:2), (laenge:2; haare:3), (laenge:5; haare:3))

Also denke ich, wird es nicht an Pointern liegen...

edit:
Die Posts haben sich Überschnitten, bei mir funzt auch Dein Prog ohne die Initialisierung.
Hast Du mal probiert in den Projektoptionen 'Optimierung' und 'Ausgerichtete Rekord-Felder' auszuschalten?

vsilverlord 8. Jan 2009 14:12

Re: denkfehler; array-> dynarray
 
ich bin jetzt nochmal alles durchgegangen. Den ganzen verdammten quelltext.
Ich hab jetzt wieder alle arrays statisch zurückgebaut.
-> siehe da, es funktioniert wieder.
Wo ich wieder beim Anfang wäre...
Gibt es Mengentypen [die so funktionieren wie arrays] mit denen ich mehr als 10000 typen speichern kann?
nein?
[die frage, warum das mit den dynamischen arrays nicht funktioniert verschieb ich auf nächstes jahr]
d.h nach 10000 durchläufen bin ich gezwungen, den stapel zu leeren, abzuspeichern und einen neuen stapel aufzubauen?
na toll.
Ach ja [ das ist jetzt nicht ironisch] vielen Dank für eure Hilfe, wenigstens habt ihr es versucht, ich bin euch sehr dankbar dafür. :thumb:
...

Klaus01 8. Jan 2009 14:17

Re: denkfehler; array-> dynarray
 
..warum gehen denn nur 10000 Elemente?
Ist der Speicher (Stack)zu gering?

Grüße
Klaus

Luckie 8. Jan 2009 14:18

Re: denkfehler; array-> dynarray
 
Warum machst du aus den Viechern keine Objekte mit Eigenschaften und Methoden? Verwalten würde ich das ganze dann in einer Containerklasse: http://www.michael-puff.de/Artikel/C...rKlassen.shtml

vsilverlord 8. Jan 2009 14:23

Re: denkfehler; array-> dynarray
 
ja, stack ist zu gering.

Klaus01 8. Jan 2009 14:26

Re: denkfehler; array-> dynarray
 
Zitat:

Zitat von vsilverlord
ja, stack ist zu gering.

.. dann mache doch aus der globalen Variablen eine lokale Variable.
edit: oder nutze dynamische Listen, wir TList oder wie schon versucht dynamische Arrays.


Grüße
Klaus

HenKst 8. Jan 2009 14:27

Re: denkfehler; array-> dynarray
 
Du könntest uns mal den genauen code von der TViech declaration und der mutier function geben

Ich sehe momentan keinen unterschied zwischen dynamischen und statischen arrays der auf den code den du uns hier gegeben hast irgendeinen Einfluss hätte. (mal von setlength abgesehn)

Wie gesagt: wenn er bei einer änderung am letzten Element im selben Schritt alle anderen ändert, sieht das für mich sehr so aus als stünden in deinem array nur pointer.

Das sollte aber a: bei dynamischen und statischen arrays gleich sein, und b: sollte das überhaupt nicht so sein wenn TViech ein record ist, weil der komplette record im array steht.

guidok 8. Jan 2009 15:09

Re: denkfehler; array-> dynarray
 
Zitat:

Zitat von Luckie
Warum machst du aus den Viechern keine Objekte mit Eigenschaften und Methoden? Verwalten würde ich das ganze dann in einer Containerklasse: http://www.michael-puff.de/Artikel/C...rKlassen.shtml

Ich würde da auch objektorientiert arbeiten. Das drängt sich ja geradezu auf.

Delphi-Quellcode:

type
  TViech = class(TCollectionItem)
  private
    FLaenge: Real;
    FHaare: Real;
    //..weitere Eigenschaften
  public
    constructor Create(Collection: TCollection); override;
    procedure Mutiere;
    procedure Assign(Source: TPersistent);
    //..weitere Methoden
    property Laenge: Real read FLaenge write FLaenge;
    property Haare: Real read FHaare write FHaare;
    //..weitere Eigenschaften
  end;

constructor TViech.Create(Collection: TCollection);
begin
  inherited;
  Laenge := 1; //Startparameter für ein Viech setzen
  Haare := 1;
end;

//Die Methode Assign brauchst du um ein Viech einem anderen Viech zuweisen zu können
procedure TViech.Assign(Source: TPersistent);
begin
  if Source is TViech then begin
    FLaenge := TViech(Source).FLaenge;
    FHaare := TViech(Source).FHaare;
    //...weitere Eigenschaften
  end;
end;
Die ganzen Viecher speicherst du in einer Collection ab.

Delphi-Quellcode:
type
  TViecher = class(TCollection)
  protected
    function GetViech(Index: Integer): TViech;
    procedure SetViech(Index: Integer; Value: TViech);
  public
    function Add: TViech;
    function Insert(Index: Integer) : TViech;
    property Viech[Index: Integer]: TViech read GetViech write SetViech; default;
  end;

function TViecher.GetViech(Index: Integer): TViech;
begin
  Result := TViech(inherited GetItem(Index));
end;

procedure TViecher.SetViech(Index: Integer; Value: TViech);
begin
  inherited SetItem(Index, Value);
end;

function TViecher.Add: TViech;
begin
  Result := TViech(inherited Add);
end;

function TViecher.Insert(Index: Integer): TViech;
begin
  Result := TViech(inherited Insert(Index));
end;
Damit stehen dir alle Wege offen.

Delphi-Quellcode:

//Irgendwo im Hauptprogramm...
var BlaueViecher: TViecher;
    RoteViecher: TViecher;

BlaueViecher := TViecher.Create(TViech); //Hier wird der Collection gesagt, von welchem Typ ihre Items sind!
RoteViecher := TViecher.Create(TViech);

//Neues Viech hinzufügen
BlaueViecher.Add //Fügt ein neues Viech mit den Standardvorgaben an

//Da "Add" eine Funktion ist, geht auch das:

var tempViech: TViech;

tempViech := BlaueViecher.Add; //tempViech verweist jetzt auf das neu angefügte Viech INNERHALB der Collection
tempViech.Mutiere; //und kann damit sofort weiter bearbeitet werden

//Eigenschaft eines Vieches ändern
BlaueViecher.Viech[1].Haare := 2;

//oder einem anderen Viech zuweisen
BlaueViecher.Viech[2].Assign(BlaueViecher.Viech[1]);

//oder mutieren
BlaueViecher.Viech[2].Mutiere;

//Die Anzahl der Viecher feststellen
BlaueViecher.Count;

Luckie 8. Jan 2009 15:18

Re: denkfehler; array-> dynarray
 
Deine Add-methode kommt mir etwas komisch vor. Sollte sie nicht so aussehen:
Delphi-Quellcode:
function TBlaueViecher.Add(Item: TViech);
begin
  // hier Item der Liste hinzufügen
end;
Es kan nnatürlich auch sein, dass ich falsdch liege und die Funktionsweise von TCollection nicht verstanden haben, da ich noch nie etwas damit gemacht habe.

vsilverlord 8. Jan 2009 15:24

Re: denkfehler; array-> dynarray
 
sieht gut aus, vor allem auch eleganter. Ich werd mir das erst mal verinnerlichen bevor ich anfange, an meinem projekt rumzuschrauben^^
aber danke trotzdem

guidok 8. Jan 2009 15:26

Re: denkfehler; array-> dynarray
 
Zitat:

Zitat von Luckie
Deine Add-methode kommt mir etwas komisch vor. Sollte sie nicht so aussehen:
Delphi-Quellcode:
function TBlaueViecher.Add(Item: TViech);
begin
  // hier Item der Liste hinzufügen
end;
Es kan nnatürlich auch sein, dass ich falsdch liege und die Funktionsweise von TCollection nicht verstanden haben, da ich noch nie etwas damit gemacht habe.

Nein, das müsste schon so passen. Ich hatte im Beispiel vergessen das Create der Collection richtig aufzurufen (ist korrigiert). Hier wird angegeben, von welchem Typ die Items sind, die die Collection aufnehmen soll.


Alle Zeitangaben in WEZ +1. Es ist jetzt 03:12 Uhr.
Seite 1 von 2  1 2      

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