Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Exception beim Schreiben in dynamisches Array?


Ecthelion - Mi 08.01.03 23:13
Titel: Exception beim Schreiben in dynamisches Array?
Hallo,

Ich nehme mal an, dass ein dynamisches Array am Anfang die Länge 0 hat. Erhöhe also vor dem Hinzufügen die Länge um 1 (setlength). Das Array selbst ist von einem Record-Typ, und soll dann an Stelle i (i:=high(array)) die werte aus einer record-variable übernehmen.

Was spricht also gegen ' array[i]:=standard; ' ?


AndyB - Do 09.01.03 00:04

Bis auf das dieses Beispiel das reservierte Wort array benutzt, spricht nichts gegen diese Zeile. Aus diesem Beispiel lässt sich somit keine Lösung für den Fehler finden.


Ecthelion - Do 09.01.03 00:37

ich hab ja ein andres wort als name benutzt...


AndyB - Do 09.01.03 01:08

Trotzdem reicht der gepostete Code nicht für das Finden eines Fehlers.


Ex0rzist - Do 09.01.03 01:42

Vielleicht liegt es an deinem Record.
Was aus deinem Record willst du denn ändern?


Ecthelion - Do 09.01.03 13:38


Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
        standard.name:=savedial.Edit1.Text;
        standard.xvar:=StrToInt(leftedit.Text);
        standard.oben:=StrToInt(topedit.Text);
        standard.unten:=StrToInt(bottomedit.Text);
        SetLength(pulldown,high(pulldown)+1);
        i:=high(pulldown);
        pulldown[i]:=standard;
        AssignFile(sdatei,'settings.dat');
        ReWrite(sdatei);
        for i:=1 to high(pulldown) do write(sdatei,pulldown[i]);
        CloseFile(sdatei);


Pulldown ist der Name des arrays (of tstandard), standard der name des records (of tstandard), sdatei die name des files (of tstandard).

Nach Eingabe eines Namen für dieses setting (komplett zu speichern mit name und 3 werten) soll also alles übernommen werden. Dann geht tot.

Klabautermann: Code-Tags eingefügt.


wulfskin - Do 09.01.03 15:05

Hallo Ecthelion!

Habe deinen Code nur kurz überflogen und einen Fehler festgestellt. In Zeile 5 möchtest du die Größe des Arrays um eins erhöhen. Die aktuelle Größe jedoch bekommst du nicht mit High heraus, sondern mit Length! Ersetze also den Befehl High durch Length und schau ob es klappt!
Kurze Erklärung warum High falsch ist:
Wenn das Array leer ist, wird mit High -1 zurückgegeben. Wenn das Array dynamisch ist wird bei einem Inhalt 0 ausgegeben, dass 0 das höchste Element ist. Es müsste jedoch eins sein!

Gruß wulfskin!


Ecthelion - Do 09.01.03 16:36

Ja, das hat geholfen, aber jetz tritt ein noch viel dümmeres Problem auf:

Nachdem diese Prozedur nun beendet ist, erhalte ich einen Stack-Overflow-Fehler. Habe also in Einzelanweisung ausgeführt und stelle fest, dass die Prozedur normal beendet wird und danach ständig in einer OnTimer-Prozedur vom Anfang an das Ende gesprungen wird (da Inhalt der PRozedur nur bei bestimmter Vorraussetzung ausgeführt) und dann wieder an den Anfang. Könnte diese leere OnTimer-Ausführung den Stack Overflow verursachen? Und warum komme ich dann gar nicht mehr zum bedienen des Programms?


AXMD - Sa 11.01.03 17:27

Hi,

hast du das dynamische Array mit New initialisiert?

AXMD


wulfskin - Sa 11.01.03 18:33

AXMD hat folgendes geschrieben:
Hi,

hast du das dynamische Array mit New initialisiert?

AXMD
Muss man nicht, bzw. mach ich nie und es klappt trotzdem!

Gruß Hape!


AndyB - Sa 11.01.03 20:33

wulfskin hat folgendes geschrieben:
AXMD hat folgendes geschrieben:
hast du das dynamische Array mit New initialisiert?

AXMD
Muss man nicht

Das ergibt auch eine Compiler Fehlermeldung:
New wird für dynamische Arrays nicht unterstützt - es muss Setlength verwendet werden.


Ecthelion - So 12.01.03 21:20

Muss es etwa auch mit SetLength (name,1) initialisiert werden?

Und selbst wenn, mein aktuelles Problem ist ja ein ganz andres. Wieso bekomm ich jetz nen stack overflow?


AndyB - So 12.01.03 21:37

Da wird wohl etwas rekursiv aufgerufen. Hast du schon mal versucht den Timer über Timer.Enabled := False beim Eintreten in OnTimer auszuschalten und vor dem Verlassen wieder mit Timer.Enabled := True zu reaktivieren.


Ecthelion - Mo 13.01.03 00:12

Versteh ich jetz nich ganz, was soll das bewirken?


Ecthelion - Mo 13.01.03 00:14

Achso, damit der Timer nich OnTimer-mäßig aufgerufen werden kann während das OnTimer-Modul läuft? Noch nicht versucht.

Im Übrigen taucht das Problem mit dem stack overflow nur auf, wenn ich in dem anderen Formular die Sache mit dem dyn. Array teste. Im Programm selbst gibt's mit dem Timer keine Probleme...


Brueggendiek - Mo 13.01.03 02:55

Hallo!

Ecthelion hat folgendes geschrieben:
Versteh ich jetz nich ganz, was soll das bewirken?


Wenn die im OnTimer eingetragene Prozedur länger braucht, als das Timer-Intervall ist (z.B. wenn eine Eingabe aufgerufen wird), wird OnTimer nach Ablauf der Zeit erneut gestartet, so daß die Prozedur mehrfach läuft. Das kann natürlich zu unerwünschten Effekten kommen.

Wenn zu erwarten ist, daß OnTimer zu lange braucht, sollte man den Timer am Anfang ausschalten (Enabled := False) und am Ende wieder einschalten (Enabled := True) - dann kann nur eine Instanz laufen.

Gruß

Dietmar Brüggendiek