Seite 1 von 3
Größe von Fixed Strings
Verfasst: 06.11.2007 10:46
von Little John
Hallo zusammen,
bei der Übersetzung eines Programms auf der MSDN-Website von C nach PureBasic ist ein merkwürdiges Problem aufgetreten. Das folgende Programmfragment hängt sich auf (getestet mit PB 4.10 Beta 3 unter Windows XP Pro SP 2):
Code: Alles auswählen
#MAX_VALUE_NAME = 16383
; #MAX_VALUE_NAME = 11000
Procedure QueryKey()
Protected achValue.s{#MAX_VALUE_NAME}
Debug "OK"
EndProcedure
QueryKey()
Wenn die Konstante z.B. den Wert 11000 hat hängt sich das Programm hingegen
nicht auf.
In der Hilfe zu den Variablentypen steht aber für Fixed String: "Range unlimited". Und bei 2 Gigabyte Arbeitsspeicher habe ich auch noch etwas Platz frei.

Ich vermute hier handelt es sich um einen Bug.
Gruß, Little John
Verfasst: 06.11.2007 10:52
von rolaf
Zur Info: Unter Beta 4 und Win2k habe ich hier das gleiche Verhalten.
Verfasst: 06.11.2007 11:03
von Kiffi
Falo hat geschrieben:Zur Info: Unter Beta 4 und Win2k habe ich hier das gleiche Verhalten.
Die Grenze liegt (bei mir) bei 16320 Zeichen:
#MAX_VALUE_NAME = 16320 ; geht
#MAX_VALUE_NAME = 16321 ; geht nicht
Grüße ... Kiffi (Beta 4 & Windows XP SP2)
Verfasst: 06.11.2007 11:38
von Rings
also, in Proceduren wird der Stack für Variablen benutzt.
(Thema Tread-Sicherheit)
Normale Strings betrifft das nicht, aber fixed strings schon.
Abhilfe:
Bei den Linker-Optionen den Stack hochsetzen,
Schreibt ne textdatei wo das drin steht:
/Stack:Neue Größe
Ausserhalb von Proceduren klappts übrigens, da dort
anders der speicher reserviert wird.
Verfasst: 06.11.2007 12:46
von Little John
Rings, vielen Dank für die Erklärung!
Da wäre es schön, wenn PB in so einem Fall eine Fehlermeldung wie z.B. "Stack nicht groß genug". o.Ä. anzeigen würde.
Und in der Hilfe zu
Fixed String sollte besser etwa stehen:
Größe außerhalb von Prozeduren unbegrenzt, innerhalb von Prozeduren abhängig von der aktuellen Stack-Größe
Rings hat geschrieben:Abhilfe:
Bei den Linker-Optionen den Stack hochsetzen,
Schreibt ne textdatei wo das drin steht:
/Stack:Neue Größe
Dazu habe ich auch nichts in der Hilfe gefunden (oder stehe ich grad' auf dem Schlauch?).
Wie muss die Textdatei heißen, und in welchem Verzeichnis muss sie sich befinden?
Danke, Little John
Verfasst: 06.11.2007 13:03
von Rings
Little John hat geschrieben:Rings, vielen Dank für die Erklärung!
ab und an kann man ja mal paar internas ausplaudern.
Findet man recht einfach heraus indem man mit /Commented
kompiliert.
Little John hat geschrieben:
Da wäre es schön, wenn PB in so einem Fall eine Fehlermeldung wie z.B. "Stack nicht groß genug". o.Ä. anzeigen würde.
Und in der Hilfe zu
Fixed String sollte besser etwa stehen:
Größe außerhalb von Prozeduren unbegrenzt, innerhalb von Prozeduren abhängig von der aktuellen Stack-Größe
Ja, sehe ich auch so.
Little John hat geschrieben:
Dazu habe ich auch nichts in der Hilfe gefunden (oder stehe ich grad' auf dem Schlauch?).
Wie muss die Textdatei heißen, und in welchem Verzeichnis muss sie sich befinden?
polink.exe (im Compiler verzeichnis) aufrufen mit :
Polink /?
Im PBEditor unter Compiler-Optionen bei Linker-OptionenDatei den Datei Namen eintragen.
Verfasst: 06.11.2007 13:10
von Rings
Verfasst: 06.11.2007 14:38
von Little John
PB bietet so viele Möglichkeiten ...
Finde ich im Prinzip auch toll, aber es ist schwer da den Überblick zu bekommen.
Vielen Dank nochmal für die Hinweise!
Leider funktioniert das Code-Schnipsel aus meinem ersten Beitrag immer noch nicht.
Zuerst hatte ich in die Datei geschrieben
/Stack:32000
... ohne Erfolg. Dann habe ich den Wert immer weiter vergrößert, bis ich zum Schluss hatte
/Stack:67108864
Das sind 64 MB.

Das Programm verhält sich immer noch wie am Anfang.
Ich hatte zwischendurch probehalber 'mal zwischen Doppelpunkt und Zahl ein Leerzeichen geschrieben.
Dabei generierte PB einen "fatal error", wodurch verifiziert war dass die Textdatei mit der Linker-Option
tatsächlich gelesen wird. Wat nu?
Danke!
Gruß, Little John
Verfasst: 06.11.2007 23:19
von HeX0R
Du kannst dir auch so helfen:
Code: Alles auswählen
;------- Some Local Fixed Strings Helpers -----------
Structure _LOCAL_FIXED_STRUCTURE_
Length.l
*String
EndStructure
Procedure.l CREATE_LOCAL_FIXED_STRING(Length.l)
Protected *a._LOCAL_FIXED_STRUCTURE_
*a = AllocateMemory(4 + Length * SizeOf(CHARACTER))
*a\Length = Length
ProcedureReturn *a
EndProcedure
Procedure.l FILL_LOCAL_FIXED_STRING(*a._LOCAL_FIXED_STRUCTURE_, String.s)
If StringByteLength(String) < *a\Length
CopyMemory(@String, *a + OffsetOf(_LOCAL_FIXED_STRUCTURE_\String), StringByteLength(String) + SizeOf(CHARACTER))
Else
CopyMemory(@String, *a + OffsetOf(_LOCAL_FIXED_STRUCTURE_\String), *a\Length)
EndIf
EndProcedure
Procedure.s READ_LOCAL_FIXED_STRING(*a._LOCAL_FIXED_STRUCTURE_)
ProcedureReturn PeekS(*a + OffsetOf(_LOCAL_FIXED_STRUCTURE_\String), *a\Length)
EndProcedure
Macro FREE_LOCAL_FIXED_STRING(a)
FreeMemory(a)
EndMacro
;---------------------------
#MAX_VALUE_NAME = 16384
; #MAX_VALUE_NAME = 11000
Procedure QueryKey()
Protected *achValue = CREATE_LOCAL_FIXED_STRING(#MAX_VALUE_NAME)
FILL_LOCAL_FIXED_STRING(*achValue, "Ja Mei, wie kimmst denn du da her ?")
Debug READ_LOCAL_FIXED_STRING(*achValue)
FREE_LOCAL_FIXED_STRING(*achValue)
EndProcedure
QueryKey()
Verfasst: 07.11.2007 00:34
von Little John
Hallo HeX0R,
danke!
So ähnlich -- also basierend auf AllocateMemory() -- habe ich es jetzt schon gemacht. Ich hatte aber nicht so eine schöne Lösung entwickelt wie Du. Du hast ja quasi den Datentyp FIXED STRING neu implementiert. Solche allgemeingültigen Lösungen finde ich immer sehr gut.
Gruß, Little John