Hilfe!!! Zeiger zeigt plötzlich ins Nirvana

Für allgemeine Fragen zur Programmierung mit PureBasic.
Benutzeravatar
Didelphodon
Beiträge: 360
Registriert: 18.12.2004 13:03
Wohnort: Wien
Kontaktdaten:

Hilfe!!! Zeiger zeigt plötzlich ins Nirvana

Beitrag von Didelphodon »

Hallo!

Der nachstehende Code ist grauslich zu lesen weil (von meinem Klassen-PreCompiler) generiert. Leider hauts das ganze aufgrund eines Zeigers, der ins Nirvana zeigt auf, warum es dazu aber kommt, kann ich beim besten Willen nicht nachvollziehen. Jetzt, nach 6 Stunden Fehlersuche, würd ich Euch mal bitten drüberzukucken - vielleicht bin ich ja schon BLIND.
Ich habe das CallDebugger und Debugs entsprechend gesetzt, dass man sieht, wo die beteiligten Zeiger gerade hinzeigen. Das Phänomen ist, dass der Zeiger *o in der add-Procedure die ganze Zeit aufs richtige zeigt, bis der Kopf der While-Schleife ausgeführt wird; dann zeigt er irgendwo hin.

Hier der Code, und toi toi toi:

Code: Alles auswählen

; %%PBPP%%:CLASS
; %%PBPP%%:SUBSTITUTED=Class object
Interface pbppfi_object; %%PBPP%%:GENERATED
    beforeDestruct(); %%PBPP%%:GENERATED
    destruct(); %%PBPP%%:GENERATED
EndInterface; %%PBPP%%:GENERATED
Structure pbppfs_object; %%PBPP%%:GENERATED
    beforeDestruct.l; %%PBPP%%:GENERATED
    destruct.l; %%PBPP%%:GENERATED
EndStructure; %%PBPP%%:GENERATED
Structure pbppos_object; %%PBPP%%:GENERATED
    virtualTable.l; %%PBPP%%:GENERATED
    functions.l[2]
EndStructure; %%PBPP%%:GENERATED
    Procedure pbppm_object_beforeDestruct(*this.pbppos_object); %%PBPP%%:SUBSTITUTED=    Method beforeDestruct()
        *thismeth.pbppfi_object = *this; %%PBPP%%:GENERATED
    EndProcedure; %%PBPP%%:SUBSTITUTED=    EndMethod

    Procedure pbppm_object_destruct(*this.pbppos_object); %%PBPP%%:SUBSTITUTED=    Method destruct()
        *thismeth.pbppfi_object = *this; %%PBPP%%:GENERATED
        *thismeth\beforeDestruct()
        FreeMemory(*this\virtualTable)
        FreeMemory(*thismeth)
    EndProcedure; %%PBPP%%:SUBSTITUTED=    EndMethod
; %%PBPP%%:GENERATED
Procedure.l pbppc_Newobject(); %%PBPP%%:GENERATED
    Protected *pbppos_.pbppos_object; %%PBPP%%:GENERATED
    *pbppos_ = AllocateMemory(SizeOf(pbppos_object)); %%PBPP%%:GENERATED
    *pbppos_\virtualTable = *pbppos_ + OffsetOf(pbppos_object\functions)
    *pbppos_\functions[0] = @pbppm_object_beforeDestruct(); %%PBPP%%:GENERATED
    *pbppos_\functions[1] = @pbppm_object_destruct(); %%PBPP%%:GENERATED
    ProcedureReturn *pbppos_; %%PBPP%%:GENERATED
EndProcedure; %%PBPP%%:GENERATED
; %%PBPP%%:SUBSTITUTED=EndClass
; %%PBPP%%:ENDCLASS

; %%PBPP%%:CLASS
; %%PBPP%%:SUBSTITUTED=Class ListElement Extends Object
Interface pbppfi_ListElement; %%PBPP%%:GENERATED
    addListElement(*element.pbppfi_ListElement); %%PBPP%%:GENERATED
    setNextElement(reference.l); %%PBPP%%:GENERATED
    setPreviousElement(reference.l); %%PBPP%%:GENERATED
    setData(reference.l); %%PBPP%%:GENERATED
    getData.l(); %%PBPP%%:GENERATED
    getNextElement.l(); %%PBPP%%:GENERATED
    getPreviousElement.l(); %%PBPP%%:GENERATED
    beforeDestruct(); %%PBPP%%:GENERATED
    destruct(); %%PBPP%%:GENERATED
EndInterface; %%PBPP%%:GENERATED
Structure pbppfs_ListElement; %%PBPP%%:GENERATED
    addListElement.l; %%PBPP%%:GENERATED
    setNextElement.l; %%PBPP%%:GENERATED
    setPreviousElement.l; %%PBPP%%:GENERATED
    setData.l; %%PBPP%%:GENERATED
    getData.l; %%PBPP%%:GENERATED
    getNextElement.l; %%PBPP%%:GENERATED
    getPreviousElement.l; %%PBPP%%:GENERATED
    beforeDestruct.l; %%PBPP%%:GENERATED
    destruct.l; %%PBPP%%:GENERATED
EndStructure; %%PBPP%%:GENERATED
Structure pbppos_ListElement; %%PBPP%%:GENERATED
    virtualTable.l; %%PBPP%%:GENERATED
    functions.l[9]
    *previousElement.pbppfi_ListElement
    *nextElement.pbppfi_ListElement
    dataObject.l
EndStructure; %%PBPP%%:GENERATED
    
    Procedure pbppm_ListElement_addListElement(*this.pbppos_ListElement,*element.pbppfi_ListElement); %%PBPP%%:SUBSTITUTED=    Method addListElement(*element.pbppfi_ListElement)
        *thismeth.pbppfi_ListElement = *this; %%PBPP%%:GENERATED
        *element\setNextElement(0)
        *element\setPreviousElement(*thismeth)
        *this\nextElement = *element
    EndProcedure; %%PBPP%%:SUBSTITUTED=    EndMethod
        
    Procedure pbppm_ListElement_setNextElement(*this.pbppos_ListElement,reference.l); %%PBPP%%:SUBSTITUTED=    Method setNextElement(reference.l)
        *thismeth.pbppfi_ListElement = *this; %%PBPP%%:GENERATED
        *this\nextElement = reference
    EndProcedure; %%PBPP%%:SUBSTITUTED=    EndMethod
        
    Procedure pbppm_ListElement_setPreviousElement(*this.pbppos_ListElement,reference.l); %%PBPP%%:SUBSTITUTED=    Method setPreviousElement(reference.l)
        *thismeth.pbppfi_ListElement = *this; %%PBPP%%:GENERATED
        *this\previousElement = reference
    EndProcedure; %%PBPP%%:SUBSTITUTED=    EndMethod
        
    Procedure pbppm_ListElement_setData(*this.pbppos_ListElement,reference.l); %%PBPP%%:SUBSTITUTED=    Method setData(reference.l)
        *thismeth.pbppfi_ListElement = *this; %%PBPP%%:GENERATED
        *this\dataObject = reference
    EndProcedure; %%PBPP%%:SUBSTITUTED=    EndMethod
        
    Procedure.l pbppm_ListElement_getData(*this.pbppos_ListElement); %%PBPP%%:SUBSTITUTED=    Method.l getData()
        *thismeth.pbppfi_ListElement = *this; %%PBPP%%:GENERATED
        ProcedureReturn *this\dataObject; %%PBPP%%:SUBSTITUTED=        MethodReturn *this\dataObject
    EndProcedure; %%PBPP%%:SUBSTITUTED=    EndMethod
        
    Procedure.l pbppm_ListElement_getNextElement(*this.pbppos_ListElement); %%PBPP%%:SUBSTITUTED=    Method.l getNextElement()
        *thismeth.pbppfi_ListElement = *this; %%PBPP%%:GENERATED
        ProcedureReturn *this\nextElement; %%PBPP%%:SUBSTITUTED=        MethodReturn *this\nextElement
    EndProcedure; %%PBPP%%:SUBSTITUTED=    EndMethod
        
    Procedure.l pbppm_ListElement_getPreviousElement(*this.pbppos_ListElement); %%PBPP%%:SUBSTITUTED=    Method.l getPreviousElement()
        *thismeth.pbppfi_ListElement = *this; %%PBPP%%:GENERATED
        ProcedureReturn *this\previousElement; %%PBPP%%:SUBSTITUTED=        MethodReturn *this\previousElement
    EndProcedure; %%PBPP%%:SUBSTITUTED=    EndMethod
        
    Procedure pbppm_ListElement_beforeDestruct(*this.pbppos_ListElement); %%PBPP%%:SUBSTITUTED=    Method beforeDestruct()
        *thismeth.pbppfi_ListElement = *this; %%PBPP%%:GENERATED
        FreeMemory(*this\dataObject)
    EndProcedure; %%PBPP%%:SUBSTITUTED=    EndMethod
    Procedure pbppm_ListElement_destruct(*this.pbppos_ListElement); %%PBPP%%:GENERATED
        *thismeth.pbppfi_ListElement = *this; %%PBPP%%:GENERATED
        *thismeth\beforeDestruct(); %%PBPP%%:GENERATED
        FreeMemory(*this\virtualTable); %%PBPP%%:GENERATED
        FreeMemory(*thismeth); %%PBPP%%:GENERATED
    EndProcedure; %%PBPP%%:GENERATED
; %%PBPP%%:GENERATED
Procedure.l pbppc_NewListElement(); %%PBPP%%:GENERATED
    Protected *pbppos_.pbppos_ListElement; %%PBPP%%:GENERATED
    *pbppos_ = AllocateMemory(SizeOf(pbppos_ListElement)); %%PBPP%%:GENERATED
    *pbppos_\virtualTable = *pbppos_ + OffsetOf(pbppos_object\functions)
    *pbppos_\functions[0] = @pbppm_ListElement_addListElement(); %%PBPP%%:GENERATED
    *pbppos_\functions[1] = @pbppm_ListElement_setNextElement(); %%PBPP%%:GENERATED
    *pbppos_\functions[2] = @pbppm_ListElement_setPreviousElement(); %%PBPP%%:GENERATED
    *pbppos_\functions[3] = @pbppm_ListElement_setData(); %%PBPP%%:GENERATED
    *pbppos_\functions[4] = @pbppm_ListElement_getData(); %%PBPP%%:GENERATED
    *pbppos_\functions[5] = @pbppm_ListElement_getNextElement(); %%PBPP%%:GENERATED
    *pbppos_\functions[6] = @pbppm_ListElement_getPreviousElement(); %%PBPP%%:GENERATED
    *pbppos_\functions[7] = @pbppm_ListElement_beforeDestruct(); %%PBPP%%:GENERATED
    *pbppos_\functions[8] = @pbppm_ListElement_destruct(); %%PBPP%%:GENERATED
    ProcedureReturn *pbppos_; %%PBPP%%:GENERATED
EndProcedure; %%PBPP%%:GENERATED
; %%PBPP%%:SUBSTITUTED=EndClass
; %%PBPP%%:ENDCLASS

; %%PBPP%%:CLASS
; %%PBPP%%:SUBSTITUTED=Class List Extends Object
Interface pbppfi_List; %%PBPP%%:GENERATED
    reset(); %%PBPP%%:GENERATED
    add(*o.pbppfi_ListElement); %%PBPP%%:GENERATED
    hasNextElement.b(); %%PBPP%%:GENERATED
    getNextElement.l(); %%PBPP%%:GENERATED
    beforeDestruct(); %%PBPP%%:GENERATED
    destruct(); %%PBPP%%:GENERATED
EndInterface; %%PBPP%%:GENERATED
Structure pbppfs_List; %%PBPP%%:GENERATED
    reset.l; %%PBPP%%:GENERATED
    add.l; %%PBPP%%:GENERATED
    hasNextElement.l; %%PBPP%%:GENERATED
    getNextElement.l; %%PBPP%%:GENERATED
    beforeDestruct.l; %%PBPP%%:GENERATED
    destruct.l; %%PBPP%%:GENERATED
EndStructure; %%PBPP%%:GENERATED
Structure pbppos_List; %%PBPP%%:GENERATED
    virtualTable.l; %%PBPP%%:GENERATED
    functions.l[6]
    *rootElement.pbppfi_ListElement
    *actualElement.pbppfi_ListElement
    endReached.b
EndStructure; %%PBPP%%:GENERATED
        
    Procedure pbppm_List_reset(*this.pbppos_List); %%PBPP%%:SUBSTITUTED=    Method reset()
        *thismeth.pbppfi_List = *this; %%PBPP%%:GENERATED
        *this\endReached = 0
        *this\actualElement = 0
    EndProcedure; %%PBPP%%:SUBSTITUTED=    EndMethod
        
    Procedure pbppm_List_add(*this.pbppos_List,*o.pbppfi_ListElement); %%PBPP%%:SUBSTITUTED=    Method add(*o.pbppfi_ListElement)
        *thismeth.pbppfi_List = *this; %%PBPP%%:GENERATED
        If (*this\rootElement = 0)
            *this\rootElement = *o
            *this\actualElement = *o
            ProcedureReturn; %%PBPP%%:SUBSTITUTED=            MethodReturn
        Else
            *this\actualElement = *this\rootElement
            Debug Str(*o)
            While (*this\actualElement\getNextElement() <> 0)
                *this\actualElement = *this\actualElement\getNextElement()
            Wend
            Debug Str(*this\actualElement)
            Debug Str(*o)
            *this\actualElement\addListElement(*o)
        EndIf
    EndProcedure; %%PBPP%%:SUBSTITUTED=    EndMethod
        
    Procedure.b pbppm_List_hasNextElement(*this.pbppos_List); %%PBPP%%:SUBSTITUTED=    Method.b hasNextElement()
        *thismeth.pbppfi_List = *this; %%PBPP%%:GENERATED
        If (*this\actualElement = 0 And *this\endReached = 0 And *this\rootElement <> 0)
            ProcedureReturn 1; %%PBPP%%:SUBSTITUTED=            MethodReturn 1
        ElseIf (*this\actualElement <> 0 And *this\actualElement\getNextElement() <> 0 And *this\endReached = 0)
            ProcedureReturn 1; %%PBPP%%:SUBSTITUTED=            MethodReturn 1
        Else
            ProcedureReturn 0; %%PBPP%%:SUBSTITUTED=            MethodReturn 0
        EndIf
    EndProcedure; %%PBPP%%:SUBSTITUTED=    EndMethod
        
    Procedure.l pbppm_List_getNextElement(*this.pbppos_List); %%PBPP%%:SUBSTITUTED=    Method.l getNextElement()
        *thismeth.pbppfi_List = *this; %%PBPP%%:GENERATED
        If (*this\actualElement = 0 And *this\endReached = 0 And *this\rootElement <> 0)
            *this\actualElement = *this\rootElement
        ElseIf (*this\actualElement <> 0 And *this\actualElement\getNextElement() <> 0 And *this\endReached = 0)
            *this\actualElement = *this\actualElement\getNextElement()
        Else
            *this\actualElement = 0
        EndIf
        ProcedureReturn *this\actualElement; %%PBPP%%:SUBSTITUTED=        MethodReturn *this\actualElement
    EndProcedure; %%PBPP%%:SUBSTITUTED=    EndMethod
        
    Procedure pbppm_List_beforeDestruct(*this.pbppos_List); %%PBPP%%:SUBSTITUTED=    Method beforeDestruct()
        *thismeth.pbppfi_List = *this; %%PBPP%%:GENERATED
        *this\actualElement = *this\rootElement
        While (*this\actualElement <> 0)
            *o.pbppfi_ListElement = *this\actualElement\getNextElement()
            *this\actualElement\destruct()
            *this\actualElement = *o
        Wend
    EndProcedure; %%PBPP%%:SUBSTITUTED=    EndMethod
    Procedure pbppm_List_destruct(*this.pbppos_List); %%PBPP%%:GENERATED
        *thismeth.pbppfi_List = *this; %%PBPP%%:GENERATED
        *thismeth\beforeDestruct(); %%PBPP%%:GENERATED
        FreeMemory(*this\virtualTable); %%PBPP%%:GENERATED
        FreeMemory(*thismeth); %%PBPP%%:GENERATED
    EndProcedure; %%PBPP%%:GENERATED
; %%PBPP%%:GENERATED
Procedure.l pbppc_NewList(); %%PBPP%%:GENERATED
    Protected *pbppos_.pbppos_List; %%PBPP%%:GENERATED
    *pbppos_ = AllocateMemory(SizeOf(pbppos_List)); %%PBPP%%:GENERATED
    *pbppos_\virtualTable = *pbppos_ + OffsetOf(pbppos_object\functions)
    *pbppos_\functions[0] = @pbppm_List_reset(); %%PBPP%%:GENERATED
    *pbppos_\functions[1] = @pbppm_List_add(); %%PBPP%%:GENERATED
    *pbppos_\functions[2] = @pbppm_List_hasNextElement(); %%PBPP%%:GENERATED
    *pbppos_\functions[3] = @pbppm_List_getNextElement(); %%PBPP%%:GENERATED
    *pbppos_\functions[4] = @pbppm_List_beforeDestruct(); %%PBPP%%:GENERATED
    *pbppos_\functions[5] = @pbppm_List_destruct(); %%PBPP%%:GENERATED
    ProcedureReturn *pbppos_; %%PBPP%%:GENERATED
EndProcedure; %%PBPP%%:GENERATED
; %%PBPP%%:SUBSTITUTED=EndClass
; %%PBPP%%:ENDCLASS

; -----------------------------------------------------------------------------

*l.pbppfi_List = pbppc_NewList(); %%PBPP%%:SUBSTITUTED=NewObject *l.List

*le.pbppfi_ListElement = pbppc_NewListElement(); %%PBPP%%:SUBSTITUTED=NewObject *le.ListElement
*do.LONG = AllocateMemory(SizeOf(LONG))
*do\l = 1
*le\setData(*do)
Debug Str(*le)
*l\add(*le)

*le.pbppfi_ListElement = pbppc_NewListElement(); %%PBPP%%:SUBSTITUTED=NewObject *le.ListElement
*do.LONG = AllocateMemory(SizeOf(LONG))
*do\l = 2
*le\setData(*do)
Debug Str(*le)
CallDebugger
*l\add(*le)

*le.pbppfi_ListElement = pbppc_NewListElement(); %%PBPP%%:SUBSTITUTED=NewObject *le.ListElement
*do.LONG = AllocateMemory(SizeOf(LONG))
*do\l = 3
*le\setData(*do)
*l\add(*le)

*le.pbppfi_ListElement = pbppc_NewListElement(); %%PBPP%%:SUBSTITUTED=NewObject *le.ListElement
*do.LONG = AllocateMemory(SizeOf(LONG))
*do\l = 4
*le\setData(*do)
*l\add(*le)

*le.pbppfi_ListElement = pbppc_NewListElement(); %%PBPP%%:SUBSTITUTED=NewObject *le.ListElement
*do.LONG = AllocateMemory(SizeOf(LONG))
*do\l = 5
*le\setData(*do)
*l\add(*le)

*l\reset()
While (*l\hasNextElement())
    *do = *l\getNextElement()
    Debug Str(*do\l)
Wend
*l\destruct()

End


; jaPBe Version=2.5.2.24
; Build=0
; FirstLine=85
; CursorPosition=152
; ExecutableFormat=Windows
; DontSaveDeclare
Herzlichen Dank im Voraus!

LG Didel
Das Leben ist ein sch*** Spiel, aber die Grafik ist irre!
Fighting for peace is like fuc*ing for virginity!
Benutzeravatar
Didelphodon
Beiträge: 360
Registriert: 18.12.2004 13:03
Wohnort: Wien
Kontaktdaten:

Beitrag von Didelphodon »

Found it!!

Ich hab das Problem gefunden! Allerdings weiss ich nicht, ob ich da einen Schei** gebaut habe, ob dies vollkommen klar oder vielleicht sogar ein Bug ist.

Der Befehl "*this\actualElement\getNextElement()" ist der Bösewicht und lässt mich darauf schließen, dass in so einer Situation der Verweis auf eine nächste (hier dritte) Ebene zu Fehlern führt. Ich habe den Code so abgeändert, dass ich alle Commands über mehrere Ebenen (in einem Schritt) mithilfe von Hilfsvariablen auf zwei Schritte aufgeteilt habe und siehe da, alles haut prima hin!!!!!!

Lösungs-Bsp.:
Von
"While (*this\actualElement\getNextElement() <> 0)"
auf
"*act.ListElement = *this\actualElement"
"While (*act\getNextElement() <> 0)"

Mit der Bitte um Aufklärung! (@Fred????)

LG Didel.
Das Leben ist ein sch*** Spiel, aber die Grafik ist irre!
Fighting for peace is like fuc*ing for virginity!
Antworten