Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
blackdrake
Anmeldungsdatum: 29.05.2007 Beiträge: 11
|
Verfasst am: 01.06.2007, 15:01 Titel: QuickBASIC zerstört meine Variablen (echt jetzt) |
|
|
Hallo.
Ich habe ein sehr seltsames Phänomen bei QuickBASIC 4.5 und QuickBASIC 7.1 gefunden. Nach dem Compilieren läuft das Programm falsch! Grund dafür ist, dass der Inhalt einer Variablen verloren geht!
Man beachte folgende Definitionen der Variablen:
Code: | DIM SHARED feld(20, 30) AS STRING * 1
DIM SHARED altfeld(20, 30) AS STRING * 1
DIM SHARED zeile$(20) 'Hierauf achten
DIM SHARED anzahl(15) AS INTEGER
DIM SHARED altzahl(15) AS INTEGER
DIM SHARED energie AS INTEGER |
Und:
Code: | DIM SHARED feld(20, 30) AS STRING * 1
DIM SHARED altfeld(20, 30) AS STRING * 1
DIM SHARED anzahl(15) AS INTEGER
DIM SHARED zeile$(20) 'Hierauf achten
DIM SHARED altzahl(15) AS INTEGER
DIM SHARED energie AS INTEGER |
Und:
Code: | DIM SHARED feld(20, 30) AS STRING * 1
DIM SHARED altfeld(20, 30) AS STRING * 1
DIM SHARED anzahl(15) AS INTEGER
DIM SHARED altzahl(15) AS INTEGER
DIM SHARED zeile$(20) 'Hierauf achten
DIM SHARED energie AS INTEGER |
Sieht gleich aus, müsste auch gleich laufen. Tut es aber nicht! Definitionen 1 und 2 führen zu einem Fehlergebnis, Definition 3 geht (wahrscheinlich).
Man beachte jetzt folgende SUB:
Code: | SUB meine_sub
FOR q = 1 TO 20
FOR w = 1 TO 30
altfeld(q, w) = feld(q, w)
PRINT energie 'Per Interpreter: 4, Nach Compiler: 4
altzahl(q) = anzahl(q) 'HIER GEHT "energie" verloren bei der EXE!!!
PRINT energie 'Per Interpreter: 4, Nach Compiler: 0
NEXT w
NEXT q
END SUB |
Was ist hier los? Kann BASIC irgendwie nicht korrekt mit dem Arbeitsspeicher umgehen? Überschreibt der Array etwa Bereiche im Arbeitsspeicher (-> Fremde Variablen), die ihm nicht gehören?
Nachdem ich "DIM SHARED zeile$(20)" verschoben habe, funktioniert das Programm scheinbar. Aber ich weiß nicht, ob es jetzt irgendeine andere Variable aus meinem Programm zerhaut, was ich vielleicht nicht sofort merke.
Da "energie" nach "altzahl" definiert ist, das verändert wird, und "energie" verloren geht, gehe ich davon aus, dass der Array eine Überlänge bekommt. Wenn ich "zeile$" dazwischenschiebe, wird "energie" nicht verändert, aber der Logik nach, müsste der Array dann "zeile$" zerhauen... omg
Gruß
blackdrake |
|
Nach oben |
|
|
Jojo alter Rang
Anmeldungsdatum: 12.02.2005 Beiträge: 9736 Wohnort: Neben der Festplatte
|
Verfasst am: 01.06.2007, 15:20 Titel: |
|
|
also am arbeitsspeicher liegt's nicht
ich tippe darauf, dass das eine der vielen macken des basic compilers ist, die auftreten können. wie groß ist dein sourcecode? vielleicht ist er einfach zu groß... _________________ » Die Mathematik wurde geschaffen, um Probleme zu lösen, die es nicht gäbe, wenn die Mathematik nicht erschaffen worden wäre.
|
|
Nach oben |
|
|
csde_rats
Anmeldungsdatum: 07.01.2007 Beiträge: 2292 Wohnort: Zwischen Sessel und Tastatur
|
|
Nach oben |
|
|
MisterD
Anmeldungsdatum: 10.09.2004 Beiträge: 3071 Wohnort: bei Darmstadt
|
Verfasst am: 01.06.2007, 16:10 Titel: |
|
|
qb hat kein inline asm.. _________________ "It is practically impossible to teach good programming to students that have had a prior exposure to BASIC: as potential programmers they are mentally mutilated beyond hope of regeneration."
Edsger W. Dijkstra |
|
Nach oben |
|
|
Mao
Anmeldungsdatum: 25.09.2005 Beiträge: 4409 Wohnort: /dev/hda1
|
Verfasst am: 01.06.2007, 16:11 Titel: |
|
|
QB unterstützt kein Inline-ASM.
Das ist nur eingebundener Hex-Code, was du wahrscheinlich meinst. _________________ Eine handvoll Glück reicht nie für zwei.
--
|
|
Nach oben |
|
|
csde_rats
Anmeldungsdatum: 07.01.2007 Beiträge: 2292 Wohnort: Zwischen Sessel und Tastatur
|
|
Nach oben |
|
|
blackdrake
Anmeldungsdatum: 29.05.2007 Beiträge: 11
|
Verfasst am: 01.06.2007, 17:17 Titel: |
|
|
Hallo.
Das Programm verwendet lediglich PIT (aber auch ohne kommt der Fehler) und eine Mausroutine mit einem eigenen INTERRUPT (CALL MyINTERRUPT).
Anzumerken ist, dass das Programm nach dem Compilieren etwas ruckelt, was jedoch durch die Windows-Einstellung XMS 0 -> Automatisch verschwindet.
Der Source ist 84 KB groß. Die EXE 97 KB (nicht selbständig).
Aber wieso sollte es nicht an der Speicherverwaltung liegen? Selbst in heutigen Programmiersprachen kommt es zu Pufferüberläufen, wenn eine Variable mehr speicher verbaucht, als ihr zugewiesen ist. Mir ist aber andererseits nicht bekannt, dass man in QuickBASIC einer Variable Speicher zuweisen muss...
Gruß
blackdrake |
|
Nach oben |
|
|
csde_rats
Anmeldungsdatum: 07.01.2007 Beiträge: 2292 Wohnort: Zwischen Sessel und Tastatur
|
Verfasst am: 01.06.2007, 17:51 Titel: |
|
|
blackdrake hat Folgendes geschrieben: | Hallo.
Der Source ist 84 KB groß. Die EXE 97 KB (nicht selbständig).
|
Soll heißen: 97 KB + 45 KB (brun45.exe, Laufzeitumgebung) = 142 Kb
640 K - 142 K = 498 K, wenn du mehr in den Speicher lädst gibts probs... _________________ If hilfreicher_Beitrag then klick(location.here)
Klick |
|
Nach oben |
|
|
blackdrake
Anmeldungsdatum: 29.05.2007 Beiträge: 11
|
Verfasst am: 01.06.2007, 18:08 Titel: |
|
|
Mh... klingt logisch. Aber 498 KB ist extrem viel Zeug für Variableninhalte.
Ich habe mal zum Test eine Zeichenkette nach "altzahl" gelegt. Nach dem Aufruf der Sub, die "altzahl" schreibt, kam eine Meldung, dass die Zeichenkette beschädigt worden sei.
Ich habe nun folgende Fragen:
- Was belegt denn nun alles Speicher?
- Belegt ein String$ immer nur soviel Platz, wie er gerade groß ist oder wäre es besser, einem String eine spezielle Größe zuzuordnen (AS String * 20) ?
- Kann man das Problem irgendwie umgehen oder Speicher freigeben? |
|
Nach oben |
|
|
csde_rats
Anmeldungsdatum: 07.01.2007 Beiträge: 2292 Wohnort: Zwischen Sessel und Tastatur
|
|
Nach oben |
|
|
Jojo alter Rang
Anmeldungsdatum: 12.02.2005 Beiträge: 9736 Wohnort: Neben der Festplatte
|
Verfasst am: 01.06.2007, 18:28 Titel: |
|
|
ihr denkt zu kompliziert und csde_rats hat nich so viel erfahrung
bc macht bereits ab code-größen von 64 kbyte probleme. spalte den code in mehrere module auf (z.B. maus-calls, PIT und so zeugs in ein eigenes BAS-modul), das hilft! _________________ » Die Mathematik wurde geschaffen, um Probleme zu lösen, die es nicht gäbe, wenn die Mathematik nicht erschaffen worden wäre.
|
|
Nach oben |
|
|
Mao
Anmeldungsdatum: 25.09.2005 Beiträge: 4409 Wohnort: /dev/hda1
|
Verfasst am: 01.06.2007, 18:33 Titel: |
|
|
Was eigentlich recht logisch ist. Ein Segment ist im RM maximal 64KB groß und QB arbeitet nicht segmentübergreifend. _________________ Eine handvoll Glück reicht nie für zwei.
--
|
|
Nach oben |
|
|
csde_rats
Anmeldungsdatum: 07.01.2007 Beiträge: 2292 Wohnort: Zwischen Sessel und Tastatur
|
Verfasst am: 01.06.2007, 18:37 Titel: |
|
|
Jojo hat Folgendes geschrieben: | csde_rats hat nich so viel erfahrung
|
Das sagtst du aber mal ein wirklich wahres Wörtchen
Zitat: |
Was eigentlich recht logisch ist. Ein Segment ist im RM maximal 64KB groß und QB arbeitet nicht segmentübergreifend.
|
[//me-sichwunder]
Warum haben die dann den die Stringgröße auf 32 Kb anstatt 64 Kb festgelegt
[///me-sichwunder] _________________ If hilfreicher_Beitrag then klick(location.here)
Klick |
|
Nach oben |
|
|
Mao
Anmeldungsdatum: 25.09.2005 Beiträge: 4409 Wohnort: /dev/hda1
|
Verfasst am: 01.06.2007, 18:41 Titel: |
|
|
Strings können wachsen, es werden nicht automatisch pro String 32 KB veranschlagt. _________________ Eine handvoll Glück reicht nie für zwei.
--
|
|
Nach oben |
|
|
csde_rats
Anmeldungsdatum: 07.01.2007 Beiträge: 2292 Wohnort: Zwischen Sessel und Tastatur
|
Verfasst am: 01.06.2007, 18:58 Titel: |
|
|
Mao hat Folgendes geschrieben: | Strings können wachsen, es werden nicht automatisch pro String 32 KB veranschlagt. |
Darauf wollte ich nicht hinaus. Ich wollte darauf hinaus, dass die maximal Größe unter der Segment größe liegt _________________ If hilfreicher_Beitrag then klick(location.here)
Klick |
|
Nach oben |
|
|
Mao
Anmeldungsdatum: 25.09.2005 Beiträge: 4409 Wohnort: /dev/hda1
|
Verfasst am: 01.06.2007, 19:15 Titel: |
|
|
Achso, dachte, das wäre 'ne Frage gewesen. _________________ Eine handvoll Glück reicht nie für zwei.
--
|
|
Nach oben |
|
|
blackdrake
Anmeldungsdatum: 29.05.2007 Beiträge: 11
|
Verfasst am: 03.06.2007, 01:55 Titel: Re: QuickBASIC zerstört meine Variablen (echt jetzt) |
|
|
Hallo.
Ich habe das Problem endlich gefunden! Es war tatsächlich ein Pufferüberlauf. Ich habe eine Variable durch eine zu große FOR-Scheife gesetzt, die gar nicht so groß dimensioniert war. Der Interpreter hat das dezent verschwiegen, aber die kompilierte EXE hat die Variablen, die danach deklariert wurden, zerstört, weil über die Grenzen geschrieben wurde.
blackdrake hat Folgendes geschrieben: | Hallo.
DIM SHARED feld(20, 30) AS STRING * 1
DIM SHARED altfeld(20, 30) AS STRING * 1
DIM SHARED zeile$(20) 'Hierauf achten
DIM SHARED anzahl(15) AS INTEGER
DIM SHARED altzahl(15) AS INTEGER
DIM SHARED energie AS INTEGER
...
SUB meine_sub
FOR q = 1 TO 20
FOR w = 1 TO 30
altfeld(q, w) = feld(q, w)
PRINT energie 'Per Interpreter: 4, Nach Compiler: 4
altzahl(q) = anzahl(q) 'HIER GEHT "energie" verloren bei der EXE!!!
PRINT energie 'Per Interpreter: 4, Nach Compiler: 0
NEXT w
NEXT q
END SUB |
Seltsamerweiße hat der Interpreter mir nur ein einziges Mal eine Laufzeit-Fehlermeldung ausgegeben, weswegen ich erst auf den Index-Überschreitungs-Fehler kam.
Gruß
blackdrake |
|
Nach oben |
|
|
Flo aka kleiner_hacker
Anmeldungsdatum: 23.06.2006 Beiträge: 1210
|
Verfasst am: 07.06.2007, 16:56 Titel: |
|
|
kenn ich nur von fb ...
mit den 64kb
und warum funzt mein einheitenumrechner mit mehr als 90kb noch? _________________ MFG
Flo
Satoru Iwata: Wer Spaß am Spielen hat, fragt nicht nach Grafik.
zum korrekten Verstaendnis meiner Beitraege ist die regelmaessige Wartung des Ironiedetektors unerlaesslich. |
|
Nach oben |
|
|
Jojo alter Rang
Anmeldungsdatum: 12.02.2005 Beiträge: 9736 Wohnort: Neben der Festplatte
|
Verfasst am: 07.06.2007, 19:38 Titel: |
|
|
1) gilt nur für QuickBasic
2) Der unkomprimierte Sourcecode darf nicht >64kb sein, sonst muss er in module aufgeteilt werden. manchmal gehen aber auch größere sources, kommt ganz drauf an. _________________ » Die Mathematik wurde geschaffen, um Probleme zu lösen, die es nicht gäbe, wenn die Mathematik nicht erschaffen worden wäre.
|
|
Nach oben |
|
|
wolfjuli
Anmeldungsdatum: 06.03.2008 Beiträge: 50
|
Verfasst am: 24.03.2008, 23:50 Titel: |
|
|
Sorry aber fällt nur mir auf dass man mit
Code: | DIM SHARED zeile$(20) |
(Man achte auf das Dollar-Zeichen) nicht Dimensionieren kann?????
Ich meine ich kann mich auch täuschen, aber bei mir spuckt schon der Übersetzer einen Fehler aus, wenn ich das versuche
Fazit: Mein Tipp ist, die Zeile umändern in
Code: | DIM SHARED zeile(20) AS STRING |
LG
Julian
PS: Wegen dem, dass du eine FOR-Schleife weiter laufen lassen hast, als du das Feld dimensioniert hast: Wie ist es möglich, dass dich der Übersetzer da drüber ließ?? _________________ Alles sollte so einfach wie möglich gemacht werden, aber nicht einfacher.
Zuletzt bearbeitet von wolfjuli am 25.03.2008, 00:01, insgesamt einmal bearbeitet |
|
Nach oben |
|
|
|