Vorsicht bei CopyStructure und übergreifende Speicher
Verfasst: 18.08.2011 04:22
Tachchen,
wie ich eben feststellen musste ist CopyStructure() keine Art von "MoveStructure" denn es taucht Folgendes Problem auf:
Folgende Situation: Ich habe eine Baum-Struktur mit Einträgen.
Nutze ich nun das CopyStructure() als MoveStructure indem ich tiefere Ebenen nach oben kopiere so werden die Nachkommen alle gelöscht.
Hier ein Beispiel:
Scheinbar wird nicht erst intern eine Kopie der Struktur erstellt, welche dann an der Zieladresse eingefügt wird, sonden sofort mit dem Überschreiben begonnen, was zur Folge hat, das während des kopierens auch die Quelle verändert wird.
Nun gut, also ist ein Zwischenspeichern nötig, wie:
Blöderweise verursachte dieser Code trotzdem seltsamme IMAs die ich leider (noch) nicht in einem Beispiel reproduzieren konnte.
Es steht jedoch fest, das es auch noch nötig ist, vor dem Einfügen ein ClearStructure() auszuführen, um das Ziel vorher "zu bereinigen".
Da CopyStructure ja selbst das Ziel durch ein InitializeStructure() initialisiert, kommt es vermutlich sonst zu dopplungen.
Hier also mein sichererer Weg für ein CopyStructure:
Noch eine Wahrnung:
Wenn man sogar eine höhere Ebene nach unten Kopiert entsteht sogar eine Endlosschleife innerhalb des CopyStructure die binnen Millisekunden den RAM dicht macht!
Auch wenn in der Hilfe steht: "Diese Funktion ist nur für fortgeschrittene Anwender und sollte mit Vorsicht verwendet werden."
Sollte man hier noch diese Hinweise geben: bezüglich übergreifender Speicher!
wie ich eben feststellen musste ist CopyStructure() keine Art von "MoveStructure" denn es taucht Folgendes Problem auf:
Folgende Situation: Ich habe eine Baum-Struktur mit Einträgen.
Nutze ich nun das CopyStructure() als MoveStructure indem ich tiefere Ebenen nach oben kopiere so werden die Nachkommen alle gelöscht.
Hier ein Beispiel:
Code: Alles auswählen
Structure Tree
String.s
Integer.i
List Child.Tree()
EndStructure
Procedure DebugTree(*Tree.Tree, Space.i=2)
Debug Space(Space)+*Tree\String
ForEach *Tree\Child()
DebugTree(*Tree\Child(), Space+2)
Next
EndProcedure
Macro Start()
Tree.Tree
Tree\String = "Root"
AddElement(Tree\Child()) : Tree\Child()\String = "Child.1"
AddElement(Tree\Child()\Child()) : Tree\Child()\Child()\String = "SubChild.1.1"
AddElement(Tree\Child()\Child()) : Tree\Child()\Child()\String = "SubChild.1.2"
AddElement(Tree\Child()) : Tree\Child()\String = "Child.2"
AddElement(Tree\Child()\Child()) : Tree\Child()\Child()\String = "SubChild.2.1"
AddElement(Tree\Child()\Child()) : Tree\Child()\Child()\String = "SubChild.2.2"
EndMacro
Start()
Debug "Ausgangssituation:"
DebugTree(Tree)
Debug ""
CopyStructure(@Tree\Child(), @Tree, Tree)
Debug "Nach dem Kopieren von Child.2 nach Root:"
DebugTree(Tree)
Debug "ubs da fehlen ja die Kinder!"
Debug ""
Start()
Debug "noch mal Ausgangssituation:"
DebugTree(Tree)
Debug ""
CopyStructure(@Tree\Child(), @SaveTree.Tree, Tree)
CopyStructure(@SaveTree, @Tree, Tree)
Debug "Nach dem Kopieren von Child.2 nach Root:"
DebugTree(Tree)
Debug "OK, Kinder sind auch da"
Nun gut, also ist ein Zwischenspeichern nötig, wie:
Code: Alles auswählen
CopyStructure(@Tree\Child(), @SaveTree.Tree, Tree)
CopyStructure(@SaveTree, @Tree, Tree)
Es steht jedoch fest, das es auch noch nötig ist, vor dem Einfügen ein ClearStructure() auszuführen, um das Ziel vorher "zu bereinigen".
Da CopyStructure ja selbst das Ziel durch ein InitializeStructure() initialisiert, kommt es vermutlich sonst zu dopplungen.
Hier also mein sichererer Weg für ein CopyStructure:
Code: Alles auswählen
CopyStructure(@Tree\Child(), @SaveTree.Tree, Tree)
ClearStructure(@Tree, Tree)
CopyStructure(@SaveTree, @Tree, Tree)
Wenn man sogar eine höhere Ebene nach unten Kopiert entsteht sogar eine Endlosschleife innerhalb des CopyStructure die binnen Millisekunden den RAM dicht macht!
Code: Alles auswählen
; WAHRUNG ! RAM-ÜBERLASTUNG IN WENIGEN MILLISEKUNDEN!
Structure Tree
List Child.Tree()
EndStructure
Tree.Tree
AddElement(Tree\Child())
CopyStructure(@Tree, Tree\Child(), Tree)
; WAHRUNG ! RAM-ÜBERLASTUNG IN WENIGEN MILLISEKUNDEN!
Sollte man hier noch diese Hinweise geben: bezüglich übergreifender Speicher!