Seite 1 von 1

PokeS ohne AllocateMemory?

Verfasst: 04.01.2021 17:17
von 4Planes
Hallo!

Ich dachte, ich hätte eine clevere Methode gefunden, um meinen Code einfacher und gleichzeitig flexibler zu machen, indem ich Pointer und Poke-Befehle verwende. Das hat auch so lange funktioniert, wie ich nur mit Zahlen gearbeitet habe. Bei der Verwendung von Strings bin ich auf zwei Probleme gestoßen.

Hier ist ein Beispiel-Code:

Code: Alles auswählen

Structure Settings
  ZOffset.b
  Name.s
  Speed.i
EndStructure
Global Settings.Settings

; Ohne diese Zeile gehts nicht:
Settings\Name="irgendwas"
;==============================

PokeB(@Settings\ZOffset, 7)
PokeS(@Settings\Name, "Test")
PokeI(@Settings\Speed, 999)

OpenConsole("Zeiger")
PrintN(Settings\Name)
PrintN(Str(Settings\ZOffset))
PrintN(Str(Settings\Speed))
Input()
Problem Nr. 1:
@Settings\Name ist anfangs immer 0. @Settings\Name bekommt nur eine richtige Adresse im Speicher, wenn ich vorher etwas wie Settings\Name="irgendwas" ausführe. Das gilt aber komischwerweise nur für Strings. Settings\Speed ist zwar 0, aber @Settings\Speed nicht.

Problem Nr. 2:
Wenn ich hier PokeS(@Settings\Name, "Test") statt "Test" einen längeren Namen eingebe als oben bei Settings\Name="irgendwas" stürzt das Programm ab oder verhält sich seltsam. Ich nehme an, dass das daran liegt, dass Speicher überschrieben wird, der nicht überschrieben werden sollte.

Bei allen Beispielen, die ich hier im Forum gefunden habe, wird PokeS() immer in Verbindung mit AllocateMemory() verwendet. Mir ist aber nicht klar, wie man das in diesem Fall umsetzen kann.

Für Tipps, wie man den Code zum Laufen kriegen kann, wäre ich dankbar. Falls das überhaupt kein sinnvoller Ansatz ist, mit Variablen umzugehen, wäre ich auch für den Hinweis dankbar.

Re: PokeS ohne AllocateMemory?

Verfasst: 04.01.2021 18:01
von NicTheQuick
Das Feld "Name" ist nur ein Pointer auf den eigentlichen Inhalt des Strings. Liest du von oder schreibst du in das Feld mit den normalen PB-Befehlen wird automatisch festgestellt, ob ein zu schreibender String noch an die selbe Speicherstelle passt oder nicht. Falls nicht, wird neuer Speicher alloziert, der String dort hin geschrieben, der alte Speicher freigegeben und der Pointer an die neue Stelle umgebogen.
PokeS macht das alles nicht. Das arbeitet low-level, das heißt es geht immer davon aus, dass an der Stelle genug Speicher zur Verfügung steht und schreibt einfach los. Falls dort nicht genug ist, gibt es entweder schon beim Schreiben einen Fehler oder es taucht erst einer im späteren Programmverlauf auf.

Was hast du eigentlich genau vor? Wieso willst du alles mit Poke und Peek machen? Es gibt ein paar Tricks mit Strings, die dir vielleicht weiterhelfen könnten.

Re: PokeS ohne AllocateMemory?

Verfasst: 04.01.2021 18:05
von HeX0R
Das liegt am internen Stringhandling von PB, das lässt sich nicht so einfach aushebeln.
Das einfachste wäre, wenn Du dem String eine Länge mitgibst, also so in etwa:

Code: Alles auswählen

Structure Settings
  ZOffset.b
  Name.s{32}
  Speed.i
EndStructure
Dann würde alles wieder wie gewünscht funktionieren, Du bist aber leider dann in der Länge beschränkt.

Re: PokeS ohne AllocateMemory?

Verfasst: 04.01.2021 18:39
von ccode_new
Hallo 4Planes,

alles was du hier mit:
PokeS(@Settings\Name, "Test")
machen willst, macht dieser Aufruf:
Settings\Name = "Test"
doch automatisch für dich, oder ?

Wozu das PokeS() ?

Re: PokeS ohne AllocateMemory?

Verfasst: 04.01.2021 19:03
von 4Planes
HeX0R hat geschrieben:Das liegt am internen Stringhandling von PB, das lässt sich nicht so einfach aushebeln.
Das einfachste wäre, wenn Du dem String eine Länge mitgibst, also so in etwa:

Code: Alles auswählen

Structure Settings
  ZOffset.b
  Name.s{32}
  Speed.i
EndStructure
Dann würde alles wieder wie gewünscht funktionieren, Du bist aber leider dann in der Länge beschränkt.
Vielen Dank! Das hilft doch weiter. :allright: Ich begrenze einfach den String Name in der Länge − 32 sollte sogar reichen − und dann passt das.
NicTheQuick hat geschrieben: Was hast du eigentlich genau vor? Wieso willst du alles mit Poke und Peek machen? Es gibt ein paar Tricks mit Strings, die dir vielleicht weiterhelfen könnten.
ccode_new hat geschrieben:Wozu das PokeS() ?
Peek / Poke ist mir eigentlich nicht wichtig. Mir gehts darum, mit Pointern auf Variablen zu verweisen und diesen Pointer an Prozeduren weitergeben zu können. Aber irgendwann muss man dann halt den Wert der Variable ändern und da kommt dann Poke ins Spiel. In meinem Code-Beispiel tauchte nur Poke auf, weil das der einzige Punkt ist, der mir Probleme macht.

Re: PokeS ohne AllocateMemory?

Verfasst: 04.01.2021 21:44
von NicTheQuick
Aber du übergibst doch normalerweise nicht einzelne Felder per Pointer, sondern eher die ganze strukturierte Variable.
Hier ein Beispiel für Strings, das dir vielleicht trotzdem hilft.

Code: Alles auswählen

EnableExplicit

Define name.String

Procedure changeName(*name.String)
	*name\s = "Dieser String ist extra etwas länger um zu zeigen, dass es klappt"
EndProcedure


name\s = "4Planes"

Debug name\s

changeName(@name)

Debug name\s
Oder angelehnt an dein Beispiel von eben

Code: Alles auswählen

EnableExplicit

Structure Settings
	ZOffset.b
	Name.s
	Speed.i
EndStructure
Define Settings.Settings

Procedure changeSettings(*setting.Settings)
	*setting\Name = "Dieser String ist extra etwas länger um zu zeigen, dass es klappt"
EndProcedure

changeSettings(Settings)


Debug Settings\Name
Debug Settings\ZOffset
Debug Settings\Speed