Pointer-LinkedList wird nicht sortiert

Hier werden, insbesondere in den Beta-Phasen, Bugmeldungen gepostet. Das offizielle BugForum ist allerdings hier.
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Pointer-LinkedList wird nicht sortiert

Beitrag von NicTheQuick »

Wieso funktioniert dieser Code:

Code: Alles auswählen

Structure blubb
  id.l
  long.l
EndStructure

NewList ptr.blubb()

For a = 1 To 10
  AddElement(ptr())
  ptr()\id = a
  ptr()\long = Random(10000)
Next

SortStructuredList(ptr(), 0, OffsetOf(blubb\long), #PB_Sort_Long)

ForEach ptr()
  Debug ptr()\id
  Debug ptr()\long
  Debug ""
Next
Aber dieser hier nicht?

Code: Alles auswählen

Structure blubb
  id.l
  long.l
EndStructure

NewList *ptr.blubb()

For a = 1 To 10
  AddElement(*ptr())
  *ptr() = AllocateMemory(SizeOf(blubb))
  *ptr()\id = a
  *ptr()\long = Random(10000)
Next

SortStructuredList(*ptr(), 0, OffsetOf(blubb\long), #PB_Sort_Long)

ForEach *ptr()
  Debug *ptr()\id
  Debug *ptr()\long
  Debug ""
Next
Oder setze ich da die Pointer-LinkedList nur falsch ein? Ich glaube nicht!
Benutzeravatar
Ligatur
Beiträge: 196
Registriert: 09.07.2006 00:41

Beitrag von Ligatur »

Hallo,
in der Linked List speicherst du ja nur die Pointer und nicht irgendwelche Werte. Änderst du deinen Code so ab:

Code: Alles auswählen

Structure blubb 
  id.l 
  long.l 
EndStructure 

NewList *ptr.blubb() 

For a = 1 To 10 
  AddElement(*ptr()) 
  *ptr() = AllocateMemory(SizeOf(blubb)) 
  *ptr()\id = a 
  *ptr()\long = Random(10000) 
Next 

; SortStructuredList(*ptr(), 0, OffsetOf(blubb\long), #PB_Sort_Long) 
SortStructuredList(*ptr(), 0, 0, #PB_Sort_Long) 

ForEach *ptr() 
  Debug *ptr()\id 
  Debug *ptr()\long 
  Debug *ptr()
  Debug "" 
Next
dann wird nach den Adressen sortiert, unter den deine Daten gespeichert sind, so wie du das machst wird nach irgendwelchen Werten sortiert, die sich jeweils hinter den in der Linked List gespeicherten Adressen befinden, also wohl irgendwelche zufällige Werte.
Benutzeravatar
PureLust
Beiträge: 1145
Registriert: 21.07.2005 00:02
Computerausstattung: Hab aktuell im Grunde nur noch 'nen Lenovo Yoga 2 Pro im Einsatz.
Wohnort: am schönen Niederrhein

Beitrag von PureLust »

Hi NTQ,

durch "NewList *ptr.blubb()" erstellst Du ja im Grunde nur eine LL mit einem einzelnen Longwert (einem Pointer mit der Adresse aus "AllocateMemory()").
Da der "SortStructuredList()" Befehl zum Sortieren einfach nur zur Speicheradresse des Pointers den angegebenen Offset hinzuaddiert und dort dann den Wert ausliest, kann das natürlich nicht funktionieren.
(Wie ja bereits Ligatur sagte, stehen da ja dann irgendwelche willkürlichen Werte.)

Obwohl sich mir der Zweck eines solchen Konstrukts nicht ganz erschließt, nehme ich mal an dass Du dafür Deine Gründe hast.
Wenn Du also unbedingt eine Sortierung für diese Geschichte benötigst, könntest Du auf den Sortieralgorithmus von >Horst< zurück greifen.
Mit dieser Methode kannst Du im Grunde ALLES sortieren - und sei es noch so komplex und abgefahren.

Gruß, PL.
[Dynamic-Dialogs] - komplexe dynamische GUIs einfach erstellen
[DeFlicker] - Fenster flimmerfrei resizen
[WinFX] - Window Effekte (inkl. 'durchklickbares' Window)
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Beitrag von NicTheQuick »

OK, dann eben das komplette Problem:

Code: Alles auswählen

Structure gross ;Ganz große Struktur
  *id
  
  Name.s
  Desc.s
  *Termin
  *Setlist
  *Cash
  Type.l
  
  ;usw.
EndStructure
Global NewList gross.gross()


;Ganz viele Elemente, zufällig sortiert
For a = 1 To 100
  If AddElement(gross())
    gross()\id = a
    gross()\Name = Str(Random(100000000))
    gross()\Type = Random(5)
  EndIf
Next


;Wir brauchen aber nur die Elemente mit Type = 1
;also zweite Liste anlegen, die auf die erste verweist
Global NewList *ToSort.gross()
ForEach gross()
  If gross()\Type = 1
    If AddElement(*ToSort())
      ;Der Pointer-LinkedList wird nur der Pointer zu den aussortierten Elementen übergeben
      *ToSort() = @gross()
    EndIf
  EndIf
Next

;Mal zum Test alles aussortierte anzeigen
ForEach *ToSort()
  Debug Str(*ToSort()\id) + " - " + Str(*ToSort()\Type) + " - " + *ToSort()\Name
Next

;Alles nach 'Name.s' sortieren
SortStructuredList(*ToSort(), 0, OffsetOf(gross\Name), #PB_Sort_String)

;Funktioniert aber nicht
Debug ""
ForEach *ToSort()
  Debug Str(*ToSort()\id) + " - " + Str(*ToSort()\Type) + " - " + *ToSort()\Name
Next
Ihr seht, ich habe zuerst eine große unsortierte Liste, von der ich aber nur
einen Teil sortieren will, nämlich alle Elemente mit 'Type.l = 1'.
Daraus erstelle ich dann diese Pointer-LinkedList und ich kann auch alles
anzeigen lassen, wie man sieht. Aber 'SortStructuredList()' funktioniert
damit nicht.

Meiner Meinung nach ist das dann ein Bug. Oder was meint ihr?

///Edit:
Bisher behelfe ich mir mit einer Hilfsstruktur:

Code: Alles auswählen

Structure gross ;Ganz große Struktur
  *id
  
  Name.s
  Desc.s
  *Termin
  *Setlist
  *Cash
  Type.l
  
  ;usw.
EndStructure
Global NewList gross.gross()


;Ganz viele Elemente, zufällig sortiert
For a = 1 To 100
  If AddElement(gross())
    gross()\id = a
    gross()\Name = Str(Random(100000000))
    gross()\Type = Random(5)
  EndIf
Next


;Wir brauchen aber nur die Elemente mit Type = 1
Structure ToSort
  *ptr.gross
  s.s
  l.l
EndStructure
Global NewList ToSort.ToSort()
ForEach gross()
  If gross()\Type = 1
    If AddElement(ToSort())
      ;Der Pointer-LinkedList wird nur der Pointer zu den aussortierten Elementen übergeben
      ToSort()\ptr = @gross()
      ToSort()\s = gross()\Name
      ToSort()\l = gross()\id
    EndIf
  EndIf
Next

;Mal zum Test alles aussortierte anzeigen
ForEach ToSort()
  Debug Str(ToSort()\ptr\id) + " - " + Str(ToSort()\ptr\Type) + " - " + ToSort()\ptr\Name
Next

;Alles nach 'Name.s' sortieren
SortStructuredList(ToSort(), 0, OffsetOf(ToSort\s), #PB_Sort_String)

;Funktioniert!
Debug ""
ForEach ToSort()
  Debug Str(ToSort()\ptr\id) + " - " + Str(ToSort()\ptr\Type) + " - " + ToSort()\ptr\Name
Next

;Alles nach '*id' sortieren
SortStructuredList(ToSort(), 0, OffsetOf(ToSort\l), #PB_Sort_Long)

;Funktioniert!
Debug ""
ForEach ToSort()
  Debug Str(ToSort()\ptr\id) + " - " + Str(ToSort()\ptr\Type) + " - " + ToSort()\ptr\Name
Next
Benutzeravatar
PureLust
Beiträge: 1145
Registriert: 21.07.2005 00:02
Computerausstattung: Hab aktuell im Grunde nur noch 'nen Lenovo Yoga 2 Pro im Einsatz.
Wohnort: am schönen Niederrhein

Beitrag von PureLust »

Wie bereits gesagt, dass was Du vorhast kann mit SortStructuredList() nicht funktionieren.
Da SortStructuredList() den Longwert nicht als Pointer betrachtet greift er natürlich auch nicht wie von Dir gewünscht auf die Daten zu, die Du mit dem Pointer referenzieren möchtest.
Intern arbeitet SortStructuredList() ja nicht mit Pointern, sondern sieht diesen ganz einfach als normalen Long-Wert an, nach dessen Wert dann sortiert wird.

Meines Erachtens nach also kein Bug, sondern eine versuchte Vergewaltigung von SortStructuredList() Deinerseits. ;)
[Dynamic-Dialogs] - komplexe dynamische GUIs einfach erstellen
[DeFlicker] - Fenster flimmerfrei resizen
[WinFX] - Window Effekte (inkl. 'durchklickbares' Window)
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Beitrag von NicTheQuick »

Warum ist die Pointer-LinkedList sonst in PB 4.0 aufgenommen worden, wenn
man sie nur nach den Pointern sortieren kann, was ziemlich dämlich ist?

Wenn SortStructuredList() damit nicht funktioniert, wünsche ich mir eben die
Änderung auf die Funktionsweise, die ich brauche und die auch wesentlich
sinnvoller ist. /:->
Benutzeravatar
Ligatur
Beiträge: 196
Registriert: 09.07.2006 00:41

Beitrag von Ligatur »

NicTheQuick hat geschrieben:Warum ist die Pointer-LinkedList sonst in PB 4.0 aufgenommen worden, wenn
man sie nur nach den Pointern sortieren kann, was ziemlich dämlich ist?

Wenn SortStructuredList() damit nicht funktioniert, wünsche ich mir eben die
Änderung auf die Funktionsweise, die ich brauche und die auch wesentlich
sinnvoller ist. /:->
Dafür müsste dies Funktion aber vollkommen umgebaut werden, es müsste nicht nur ein neues Flag #PB_SORT_POINTER geben, zusätzlich müsste dieses Flag noch mit den anderen Sort - Flags kombinierbar sein damit die Funktion weiß, wie die Daten zu interpretieren sind, auf die der Pointer zeigt.
So wie die Funktion momentan ist, kann das mit den Sortieren gar nicht funktionieren, das ist meiner Meinung nach kein Bug sondern ein fehlendes Feature.
Zuletzt geändert von Ligatur am 22.08.2007 13:36, insgesamt 1-mal geändert.
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

ein neuer Befehl SortPointerList() wär vielleicht ne lösung...
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Beitrag von NicTheQuick »

Ich dachte eigentlich, dass der Compiler merkt, wenn die Liste 'ToSort()' oder
eben '*ToSort()' heißt und dementsprechend die richtige Funktion nutzt.

Bei einer Pointer-LinkedList ist es ja egal, welche Struktur man anbindet, die
Elementgröße bleibt immer 4 Byte. So sollte es zumindest sein. 'SizeOf()'
funktioniert mit einer LinkedList ja leider nicht, sonst könnte man es
nachprüfen.
Antworten