LinkedList nicht Pointer-gerecht? [OK]

Fragen und Bugreports zur PureBasic 4.0-Beta.
Kekskiller
Beiträge: 752
Registriert: 14.09.2004 21:39
Kontaktdaten:

LinkedList nicht Pointer-gerecht? [OK]

Beitrag von Kekskiller »

Hi Leute,

kann es sein, dass Listen in Purebasic nicht ganz Pointer-gerecht aufgeteilt sind? Theretisch müsste ich ja bei mehreren, hintereinandern allozierten Listeneinträgen auch aufeinanderfolgende Speicheradressen haben. Dem ist leider nicht so, weshalb ich mir ein wenig sorgen über die Multifunktionalität meine Effekt-Funktionen in einem Spiel mache. Kleiner Beispielcode:

Code: Alles auswählen

Structure pups
  menge.b
  stufe.b
  von.s
EndStructure

NewList pupse.pups()
Define.pups *P

Macro printpups
PrintN("pups von " + *p\von)
PrintN("anzahl: " + Str(*p\menge))
Print("Fazit: ")
Select *p\stufe
  Case 0: PrintN("nur heiße luft...")
  Case 1: PrintN("nett flauschig")
  Case 2: PrintN("alle achtung...")
  Case 3: PrintN("woaaaahhww O°.°O")
EndSelect
EndMacro

AddElement(pupse())
pupse()\menge = 1
pupse()\stufe.b = 1
pupse()\von = "mama"

AddElement(pupse())
pupse()\menge = 1
pupse()\stufe.b = 2
pupse()\von = "papa"

AddElement(pupse())
pupse()\menge = 3
pupse()\stufe.b = 3
pupse()\von = "baby"

OpenConsole()

FirstElement(pupse())
*p = @pupse()
printpups
;{ fehler-prüf-ausgabe -> pointer geht um 24 byte weiter!
Debug "größe von pups: " + Str(SizeOf(pups))
Debug "pointer: " + Str(*p)
NextElement(pupse())
Debug "liste: " + Str(@pupse())
;}
*p + SizeOf(pups)
printpups
;{ fehler-prüf-ausgabe -> pointer geht um 24 byte weiter!
Debug "größe von pups: " + Str(SizeOf(pups))
Debug "pointer: " + Str(*p)
NextElement(pupse())
Debug "liste: " + Str(@pupse())
;}
*p + SizeOf(pups)
printpups
;{ fehler-prüf-ausgabe -> pointer geht um 24 byte weiter!
Debug "größe von pups: " + Str(SizeOf(pups))
Debug "pointer: " + Str(*p)
NextElement(pupse())
Debug "liste: " + Str(@pupse())
;}
Ich weiß es nicht so recht, aber er könnte natürlich auch so sein, dass aufgrund der Dynamik der Liste zwischendurch alle anderen Programme auch ihren Speicher dazwischenpacken. Aber dass wirklich JEDES MAL zwischen Zwei Elementen genau 24byte sind, ist mir unheimlich. Deshalb kam ich auf die Idee, andere Strukturgrößen ausprozuprobieren, z.b. hierbei:

Structure pups
menge.b
stufe.b
von.s
X.b oder X.w
EndStructure

gibts 24 bytes. Aber wenn ich ein Long nehme, sinds plützlich 8 byte mehr... Lustigerweise wird ab einem "X.w" auch der zweite Eintrag ausgegeben, was ansich seltsam ist -> da ja konstant 24 byte unterschied sind. Zufall? kA. Ich hätte ganz einfach eine konstante Bytegröße zum Pointer pro Eintrag zugerechnet, aber das klappt nicht, da bei weiteren Struktureinträgen dieser Abstand auch verändert wird.

Hilfe :coderselixir:
Zuletzt geändert von Kekskiller am 11.11.2006 14:06, insgesamt 1-mal geändert.
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

öh... meinst du echt, dass

Code: Alles auswählen

Structure pups 
  menge.b 
  stufe.b 
  von.s 
EndStructure 
und

Code: Alles auswählen

Structure pups 
  menge.b 
  stufe.b 
  von.s 
  X.b
EndStructure 
gleich weite abstände haben, oder hast du dich verschrieben?

.s braucht einen pointer von 4bytes.
und das listenelement müsste selber 8 bytes brauchen,
nämlich einen pointer für previous- und einen für next-element,
würde ich jedenfalls einfach mal so vermuten.
wenn du also immer dieselbe zusätzliche bytezahl hast,
liegt das an den pointern, die das listenelement selber braucht...
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Kekskiller
Beiträge: 752
Registriert: 14.09.2004 21:39
Kontaktdaten:

Beitrag von Kekskiller »

Sie haben ja auch nicht die gleichen Größen - geht ja auch nicht - aber die Pointerabstände sind anders. Abe du hast recht, es könnte an Daten innerhalb der LinkedList liegen. Nur, wie verwalte ich das ganze effektiv? Ich übergebe nähmlich Adressen der Listen und die Anzahl der Einträge und gehe dann die Adressen durch, indem ich nach jedem element pointer + strukturgröße rechne. Mittlerweile habe ich es sogar auf direkten Listenzugriff umgestellt, aber ich bekommen den gleichen Fehler, dass der Pointer falschen Zugriff hat. Und wo? Bei DeleteElement() -.- . Ich verstehe es rein garnicht, das muss doch irgendwie möglich sein, auf den Pointer einer Liste zuzugreifen, ohne dass es Speicherfehler gibt...

EDIT: Das mit den falschen Pointerposition kann man im Beispiel sehen.
Kekskiller
Beiträge: 752
Registriert: 14.09.2004 21:39
Kontaktdaten:

Beitrag von Kekskiller »

Ach, ich Blödian! Die Hilfe sagt ganz klip und klar, was los ist:
[quote=PB-Hilfe]Nur für fortgeschrittene Anwender:
Der Wert, den dieser Befehl zurückgibt, ist ein Zeiger auf das nächste Element, oder Null wenn das nächste Element nicht existiert. Die Struktur jedes Elements wird nachfolgend dargestellt:
Structure Element
*Next.Element ; Zeiger auf das nächste Element in der Liste oder Null, wenn es das letzte Element ist
*Previous.Element ; Zeiger auf das vorherige Element in der Liste oder Null, wenn es das erste Element ist

; Die Datentypen des Anwenders, mit denen die Liste erstellt wurde, folgen nach diesen
; zwei Variablen (was bedeutet, das die Anwenderdaten wie folgt gefunden werden können:
; Adresse des neuen Elements + 8
EndStructure

Sie sollten die Zeiger am Anfang der Elemente nicht verändern, das dies die Struktur der Liste durcheinander bringt, was zu allen möglichen Problemen führen kann. [/quote]

Sprich, ich habe in den Pointern rumgefummelt, es ist kein Wunder, dass nichts funktioniert hat.

Danke dir, Kaeru für den Denkanschub, wer weiß, wahrscheinlich hätte ich dann umständlicherweise doch noch AllocateMemory() verwenden müssen o_O ^^
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

yo, gerne doch...

schau dir in der Lounge im OOP-Bereich mal die Listenklasse an, vielleicht kannst du damit was anfangen.
die ist mächtiger als die nativen LL von PB,
aber aufgrund ihrer OOP-struktur auch komplexer und schwierigerer Code...
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Kekskiller
Beiträge: 752
Registriert: 14.09.2004 21:39
Kontaktdaten:

Beitrag von Kekskiller »

Hmpf, der Kram funktioniert immer noch nicht. Ich schätze ich werde eine vorgegebene Listenfunktion benutzen, oder eine ganz einfache selber bauen. Der Aufwand wäre geringer, als diesen Pimpelkram hier zu benutzen. Ich werd nicht mehr! Zum Glück ist PB so flexibel, dass man vieles selber und vor allem schneller gestalten kann als die native Vorgabe.
Benutzeravatar
#NULL
Beiträge: 2235
Registriert: 20.04.2006 09:50

Beitrag von #NULL »

ich verstehe irgendwie nicht ganz was du machen willst - ich weiß, das is mein problem <) - ..aber wenn du nur auf die LL über einen zusammenhängenden speicher zugreifen willst, dann erstell dir doch ein pointer array. dann liegen die LL-elemente zwar irgendwo, aber du hast die pointer auf jedes element in einer reihenfolge in einem block hintereineander. nur widerspricht das dann irgendwie dem LL-prinzip(?)
my pb stuff..
Bild..jedenfalls war das mal so.
Benutzeravatar
PMV
Beiträge: 2765
Registriert: 29.08.2004 13:59
Wohnort: Baden-Württemberg

Beitrag von PMV »

öh, du willst auf eine Liste zugreifen wie auf ein Array? o_O
Das kann doch nicht funktionieren ...
Eine Linkedliste lebt doch davon, dass dieser dynamisch Speicher
zugesprochen wird ... das Betriebssystem ist dafür verantwortlich, wo
dieser Speicher zugesprochen wird ... darauf hast du keinen Einfluss und
feste Werte zu benutzen ist tötlich :?

Wenn du unbedingt Blöcke haben willst nutze Arrays oder schreib dir ne
eigenes System, welches Blöckeweise Speicher resserviert ... so wie du
es brauchst. Aber das normale System einer LinkedListe wird dir da nur
im weg stehen. Vielleicht haste auch glück und so was existiert schon :D

Ach ja, der Code müsste richtig in etwa so sein :D, aber da kannste auch
gleich die PB-Befehle verwenden, oder?

Code: Alles auswählen

Structure pups 
  menge.b 
  stufe.b 
  von.s 
EndStructure 

Structure pups_ll
  *next.pups_ll
  *prev.pups_ll
  menge.b 
  stufe.b 
  von.s 
EndStructure

NewList pupse.pups() 
Define.pups_ll *P 

Macro printpups 
PrintN("pups von " + *p\von) 
PrintN("anzahl: " + Str(*p\menge)) 
Print("Fazit: ") 
Select *p\stufe 
  Case 0: PrintN("nur heiße luft...") 
  Case 1: PrintN("nett flauschig") 
  Case 2: PrintN("alle achtung...") 
  Case 3: PrintN("woaaaahhww O°.°O") 
EndSelect 
EndMacro 

AddElement(pupse()) 
pupse()\menge = 1 
pupse()\stufe.b = 1 
pupse()\von = "mama" 

AddElement(pupse()) 
pupse()\menge = 1 
pupse()\stufe.b = 2 
pupse()\von = "papa" 

AddElement(pupse()) 
pupse()\menge = 3 
pupse()\stufe.b = 3 
pupse()\von = "baby" 

OpenConsole() 

*p = FirstElement(pupse()) ; -> gibt den Pointer auf das interne LL-Element
;*p = @pupse() ; -> gibt den Pointer auf das Element selber, nicht auf das interne LL-Element
printpups 
;{ fehler-prüf-ausgabe -> pointer geht um 24 byte weiter! 
Debug "größe von pups: " + Str(SizeOf(pups)) 
Debug "pointer: " + Str(*p) 
NextElement(pupse()) 
Debug "liste: " + Str(@pupse()) 
;} 
*p = *p\next ; -> dynamische Werte, das selbe wie NextElement() ;-)
printpups 
;{ fehler-prüf-ausgabe -> pointer geht um 24 byte weiter! 
Debug "größe von pups: " + Str(SizeOf(pups)) 
Debug "pointer: " + Str(*p) 
NextElement(pupse()) 
Debug "liste: " + Str(@pupse()) 
;} 
*p = *p\next 
printpups 
;{ fehler-prüf-ausgabe -> pointer geht um 24 byte weiter! 
Debug "größe von pups: " + Str(SizeOf(pups)) 
Debug "pointer: " + Str(*p) 
NextElement(pupse()) 
Debug "liste: " + Str(@pupse()) 
;}
MFG PMV
alte Projekte:
TSE, CWL, Chatsystem, GameMaker, AI-Game DLL, Fileparser, usw. -.-
Kekskiller
Beiträge: 752
Registriert: 14.09.2004 21:39
Kontaktdaten:

Beitrag von Kekskiller »

Bild

Ich Idiot! Das konnte ja nie gut gehen -.- . Warum bin ich so verblendet gewesen? Hrmbl -.- ...

Danke euch beiden, dennoch werde ich aus reinem Trotz dieser verwunschenen Liste gegenüber meine eigene schreiben MUAHAHAHAH :twisted: :twisted: :twisted:
Benutzeravatar
mk-soft
Beiträge: 3701
Registriert: 24.11.2004 13:12
Wohnort: Germany

Beitrag von mk-soft »

Linkedlust ist eine gute Sache wenn man vorher nicht weiss wie vile elemente man braucht.
In der regel braucht man keine pointer wenn man mit linkedlist arbeitet. Es gibt genügend befehle dafür um auf die daten zu zu greifen. Nutze diese und es funktioniert alles sauber.
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Gesperrt