Structure, PeekS und DataSection falsche Adresse

Anfängerfragen zum Programmieren mit PureBasic.
Franky_FR
Beiträge: 53
Registriert: 08.05.2019 10:06

Structure, PeekS und DataSection falsche Adresse

Beitrag 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
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8675
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 32 GB DDR4-3200
Ubuntu 22.04.3 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken
Kontaktdaten:

Re: Structure, PeekS und DataSection falsche Adresse

Beitrag 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
Bild
Franky_FR
Beiträge: 53
Registriert: 08.05.2019 10:06

Re: Structure, PeekS und DataSection falsche Adresse

Beitrag 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
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8675
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 32 GB DDR4-3200
Ubuntu 22.04.3 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken
Kontaktdaten:

Re: Structure, PeekS und DataSection falsche Adresse

Beitrag 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.
Bild
Franky_FR
Beiträge: 53
Registriert: 08.05.2019 10:06

Re: Structure, PeekS und DataSection falsche Adresse

Beitrag 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 !
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8675
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 32 GB DDR4-3200
Ubuntu 22.04.3 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken
Kontaktdaten:

Re: Structure, PeekS und DataSection falsche Adresse

Beitrag 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".
Bild
Franky_FR
Beiträge: 53
Registriert: 08.05.2019 10:06

Re: Structure, PeekS und DataSection falsche Adresse

Beitrag von Franky_FR »

OK,danke, habe ich mir schon gedacht das das nicht möglich ist.
Antworten