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?

Rings hat geschrieben:Als Bug/Hinweis weitergemeldet

http://www.purebasic.fr/english/viewtop ... 516#217516
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