Seite 1 von 1

Structure, PeekS und DataSection falsche Adresse

Verfasst: 17.06.2021 12:26
von Franky_FR
Hallo,
wieso funktioniert der folgende Code nicht ?
*p hat die richtige Adresse, Debug *p\i[2] oder mit PeekS funktioniert nicht und greift auf eine völlig andere Adresse zu.

Code: Alles auswählen

Structure StringList
	i.s[0]
EndStructure

Define *p.StringList

*p = ?mydata

Debug   *p
ShowMemoryViewer(*p,?mydataend-?mydata)
; Debug @*p\i[0]
Debug PeekS(@*p\i[0])
Debug *p\i[2]
Debug *p\i[3]
Debug *p\i[4]
Debug *p\i[5]


DataSection
	mydata:
	Data.s "t1","t2","t3","t4","t5", "t6"
	mydataend:
EndDataSection

Re: Structure, PeekS und DataSection falsche Adresse

Verfasst: 17.06.2021 12:43
von NicTheQuick
Das liegt daran, dass Strings in Structuren nicht nacheinander im Speicher liegen, wenn es dynamische Strings sind.
Erstmal hier ein einfaches Beispiel:

Code: Alles auswählen

Structure myString
	s.s
EndStructure

Debug "myString hat die Größe: " + SizeOf(myString)

Define p.myString

Debug "p hat die Größe: " + SizeOf(p)

Debug ~"Setze p\\s = \"Hallihallo\""

p\s = "Hallihallo"

Debug "p hat immer noch die Größe: " + SizeOf(p)
Debug "Das heißt der String muss irgendwo anders sein."

Debug "Das hier ist die Speicherstelle der strukturierten Variable: " + StrU(p)

Debug "Das hier ist ihr Inhalt interpretiert als Integer (gleiche Größe wie myString): " + StrU(PeekI(p))

Debug "Hinter diesem Pointer liegt aber der String:" + PeekS(PeekI(p))
Warum das ganze? Strings können sich im Laufe des Programms in ihrem Inhalt und ihrer Länge ändern. Strukturen haben aber zur Laufzeit immer die selbe Größe. Deswegen kannst du einen Speicherbereich voller Strings unbekannter Länge nicht einfach einem strukturierten Pointer zuweisen.

Was du aber machen kannst, ist folgendes. Wenn deine Strings in der Datasection alle die selbe Länge haben, dann kannst du Fixed Length Strings verwenden. Es irritiert zwar etwas, dass du 3 Zeichen pro String angeben musst, obwohl die Strings in der Datasection nur 2 Zeichen haben, aber das liegt an dem Nullcharacter hinter jedem String. Fixed Length Strings haben keinen Nullcharacter, deswegen simulieren wir ihn durch ein eigenes Zeichen.

Code: Alles auswählen

Structure StringList
	i.s{3}[0]
EndStructure

Define *p.StringList

*p = ?mydata

Debug   *p
ShowMemoryViewer(*p,?mydataend-?mydata)
Debug *p\i[0]
Debug *p\i[1]
Debug *p\i[2]
Debug *p\i[3]
Debug *p\i[4]
Debug *p\i[5]


DataSection
	mydata:
	Data.s "t1", "t2", "t3", "t4", "t5", "t6"
	mydataend:
EndDataSection

Re: Structure, PeekS und DataSection falsche Adresse

Verfasst: 17.06.2021 14:37
von Franky_FR
Das heißt also, wenn ich eine Variable vom Typ Struktur anlege, ist diese immer ein Pointer auf den Speicherbereich, wo die Felder dann liegen,nur ohne * ?
Wieso erzeugt man dann ab und an Strukturen wie *variable.Struktur bzw was bewirkt das dann ?
Oops, habs mir glaube ich gerade selber beantwortet: wenn ich selber eine Adresse der Struktur zuordnen will z.b. *variable=?Label

Re: Structure, PeekS und DataSection falsche Adresse

Verfasst: 17.06.2021 14:49
von NicTheQuick
Genau, du hast es dir selbst beantwortet. Mit *ptr.struc musst du dem Pointer eine zuvor allokierte Speicheradresse selbst zuordnen. Mit var.struc wird der Speicher, den die Struktur beansprucht, automatisch auf dem Stack angelegt.

Re: Structure, PeekS und DataSection falsche Adresse

Verfasst: 17.06.2021 15:17
von Franky_FR
Klasse, danke für die schnelle Antwort und das tolle Beispiel.
Noch eine andere Frage, die jetzt nicht zum Topic/Post passt: gibt es eine Möglichkeit, Variablennamen "variabel" zu gestalten <)
Hört sich lustig an, was ich meine ist : ich brauche z.B hundert Variablen Test, Z.B String. Diese sollen dann heißen Test1,Test2,Test3...Test100.
Kann man sowas z.B über eine Schleife, Macro... erzeugen ? Mir ist schon klar, das man sowas meist über Array löst, aber mir geht es um unterschiedliche
Variablennamen. Ist vermutlich nicht möglich !

Re: Structure, PeekS und DataSection falsche Adresse

Verfasst: 17.06.2021 15:47
von NicTheQuick
Nein, das ist nicht möglich, da im Kompilat am Ende gar keine Variablennamen mehr existieren, die du per Namen ansprechen könntest.
Alternativ könntest du eine Map dafür verwenden.

Code: Alles auswählen

NewMap vars.i()

vars("Test1") = 1
vars("Test2") = 2
vars("Test3") = 3

Debug vars("Test1")
Debug vars("Test2")
Debug vars("Test3")
Allerdings kannst du pro Map natürlich nur einen Variablentyp nutzen, im Beispiel eben Integer.

Es gibt zwar auch noch Runtime-Variablen, die du tatsächlich per Namen ansprechen kannst, allerdings kannst du damit nur zuvor deklarierte Variablen, Konstanten oder Procedures ab- bzw. aufrufen. Du kannst keine neuen erzeugen. Zumindest wüsste ich nicht wie. Schau dazu mal in der Hilfe ins Modul "Runtime".

Re: Structure, PeekS und DataSection falsche Adresse

Verfasst: 17.06.2021 15:58
von Franky_FR
OK,danke, habe ich mir schon gedacht das das nicht möglich ist.