Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Werte gehen gegen Null, werden Null


Matty92 - So 09.05.10 22:30
Titel: Werte gehen gegen Null, werden Null
Hi,
bei meiner Planetensimulation habe ich folgendes Problem, und zwar werden aufeinmal sämtliche Werte 0 oder gehen gegen Null (in der Richtung 1e-19). Ich finde einfach nicht den Fehler. Ich weiß nur, dass er passiert, wenn ich die dynamischen Arrays an den Konstruktor übergebe:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
procedure TForm5.Button1Click(Sender: TObject);
begin
  if i<form1.anzahl-1 then begin
    vxarray[i]:=StrToFloat(vx.text);
    vyarray[i]:=StrToFloat(vy.text);
    xarray[i]:=StrToFloat(x.text);
    yarray[i]:=StrToFloat(y.text);
    massearray[i]:=abs(strtofloat(masse.text));
    i:=i+1;
    if planetfest.Checked then festarray[i]:=true else festarray[i]:=false;
  end else begin
              form1.mk:=tmehrkoerper.create(vxarray,vyarray,xarray,yarray,massearray,festarray);
              form1.visible:=true;
              close;
             end;

  vx.text:='';
  vy.text:='';
  x.text:='';
  y.text:='';
  masse.text:='';
  planetfest.Checked:=false;
end;


Und der dazugehörige Konstruktor:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
constructor tmehrkoerper.create(vx,vy,x,y,masse:zahlenarray;fest:boolarray);
var i:integer;
begin
  Setlength(Planeten,length(vx));
  for i:=0 to high(vx) do begin
    planeten[i]:=tplanet.create(vx[i],vy[i],x[i],y[i],masse[i],fest[i]);
  end;
  zeit:=0;
end;


Ich steh absolut auf dem Schlauch und sehe den Fehler nicht, habt ihr eine Idee?

Viele Grüße,
Matty


Xentar - So 09.05.10 22:38

Schonmal in den Projektoptionen die Bereichsprüfung aktiviert?


jaenicke - So 09.05.10 22:43

Am Rande: Wie wäre es statt dieser Zeile:

Delphi-Quelltext
1:
if planetfest.Checked then festarray[i]:=true else festarray[i]:=false;                    
mit dieser:

Delphi-Quelltext
1:
festarray[i] := planetfest.Checked;                    


Und dann fällt mir noch auf, dass du i erhöhst (Zeile 9) und danach noch auf festarray[i] zugreifst (Zeile 10). Dementsprechend ist der Zugriff auf dieses Array immer um eins verschoben. Vermutlich schreibst du also am Ende hinter dem Array irgendwo in den Speicher.
Das sollte dir dann bei wie von user profile iconXentar empfohlen aktivierter Bereichsprüfung auch Delphi sagen.

Zum Problem lässt sich ansonsten erst einmal nicht viel sagen, denn in dem Quelltextauszug ist sonst nicht viel zu sehen. Insbesondere wie du die Arrays verwendest usw.


Matty92 - Di 11.05.10 16:00

Hi Xentar,
ne, sorry, die Bereichsprüfung meldet keinen Fehler. Ich habe aber herausgefunden, dass es immer nur das letzte Feld ist, was 0 Werte hat, aber der Index ist der Richtige.

Hi Jaenicke,
ok, danke für den Hinweis, ich habe das i:=i+1 verschoben, aber es bringt keine Änderung.


Tastaro - Di 11.05.10 16:40

Wo kommt denn das i her?

Delphi-Quelltext
1:
2:
3:
4:
procedure TForm5.Button1Click(Sender: TObject);
begin
  if i<form1.anzahl-1 then begin
    vxarray[i]:=StrToFloat(vx.text);


Falls es global ist (was es nicht sein sollte) dann hast du hier

Delphi-Quelltext
1:
2:
3:
4:
5:
var i:integer;
begin
  Setlength(Planeten,length(vx));
  for i:=0 to high(vx) do begin
    planeten[i]:=tplanet.create(vx[i],vy[i],x[i],y[i],masse[i],fest[i]);


gleich zwei Variablen die i heißen.

Außerdem ist nicht ersichtlich ob i in Button1Click überhaupt mit einem gültigen Wert initialisert ist.

Beste Grüße


Matty92 - Di 11.05.10 17:04

Moderiert von user profile iconNarses: Komplett-Zitat des letzten Beitrags entfernt.

Hi Tastaro,
das i existiert nur in der Form.
Hier noch der komplette Kode:

Edit: Hab es gefunden, das if i<anzahl-1 war Schuld, wenn ich das -1 wegmache, wird das Array gefüllt, aber das Fenster wird einmal zuoft wieder resetet und verschwindet dann erst.


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
unit planetendaten;

interface

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

type
  TForm5 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Label1: TLabel;
    Label2: TLabel;
    planetfest: TCheckBox;
    Label3: TLabel;
    Label4: TLabel;
    x: TLabeledEdit;
    y: TLabeledEdit;
    Vx: TLabeledEdit;
    Vy: TLabeledEdit;
    Masse: TLabeledEdit;
    procedure FormCreate(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    i:integer;{ Private-Deklarationen }
  public
    anzahlaufruf:boolean;
    vxarray,vyarray,xarray,yarray,massearray:zahlenarray;
    festarray:boolarray;
  end;

var
  Form5: TForm5;

implementation

uses Zeichenfenster, konstanten;

{$R *.dfm}

type
  zahlenarray = array of extended;
  boolarray = array of boolean;

procedure TForm5.Button2Click(Sender: TObject);
begin
  setlength(vxarray,0);
  setlength(vyarray,0);
  setlength(xarray,0);
  setlength(yarray,0);
  setlength(massearray,0);
  setlength(festarray,0);
  i:=0;
  vx.text:='';
  vy.text:='';
  x.text:='';
  y.text:='';
  masse.text:='';
  planetfest.Checked:=false;
  close;
end;

procedure TForm5.Button1Click(Sender: TObject);
begin
  if i<form1.anzahl-1 then begin
    vxarray[i]:=StrToFloat(vx.text);
    vyarray[i]:=StrToFloat(vy.text);
    xarray[i]:=StrToFloat(x.text);
    yarray[i]:=StrToFloat(y.text);
    massearray[i]:=abs(strtofloat(masse.text));
    festarray[i]:=planetfest.checked;
  end else begin
              form1.mk:=tmehrkoerper.create(vxarray,vyarray,xarray,yarray,massearray,festarray);
              form1.visible:=true;
              close;
             end;

  vx.text:='';
  vy.text:='';
  x.text:='';
  y.text:='';
  masse.text:='';
  planetfest.Checked:=false;   i:=i+1;
end;



procedure TForm5.FormShow(Sender: TObject);
begin
  if anzahlaufruf then begin
    setlength(vxarray,form1.anzahl);
    setlength(vyarray,form1.anzahl);
    setlength(xarray,form1.anzahl);
    setlength(yarray,form1.anzahl);
    setlength(massearray,form1.anzahl);
    setlength(festarray,form1.anzahl);
    i:=0;
    anzahlaufruf:=false;      
  end;
end;

procedure TForm5.FormCreate(Sender: TObject);
begin
anzahlaufruf:=false;
i:=0;
end;

end.


Viele Grüße,
Matty


jaenicke - Di 11.05.10 18:17

user profile iconMatty92 hat folgendes geschrieben Zum zitierten Posting springen:
Edit: Hab es gefunden, das if i<anzahl-1 war Schuld, wenn ich das -1 wegmache, wird das Array gefüllt, aber das Fenster wird einmal zuoft wieder resetet und verschwindet dann erst.
Hört sich so an als wolltest du das machen:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
procedure TForm5.Button1Click(Sender: TObject);
begin
  vxarray[i] := StrToFloat(vx.Text);
  vyarray[i] := StrToFloat(vy.Text);
  xarray[i] := StrToFloat(x.Text);
  yarray[i] := StrToFloat(y.Text);
  massearray[i] := Abs(StrToFloat(masse.Text));
  festarray[i] := Planetfest.Checked;
  if i = form1.anzahl - 1 then
  begin
    Form1.mk := TMehrkoerper.Create(vxarray, vyarray, xarray, yarray, massearray, festarray);
    Form1.Visible := true;
    Close;
  end;

  vx.Text := '';
  vy.Text := '';
  x.Text := '';
  y.Text := '';
  masse.Text := '';
  planetfest.Checked := false;
  i := i + 1;
end;


Matty92 - Di 11.05.10 19:45

Moderiert von user profile iconNarses: Komplett-Zitat des letzten Beitrags entfernt.

Ok, danke, genau das war es. Manchmal sind die Dinge einfacher als sie scheinen zu sein.