Struktur wird aus Pointer fehlerhaft befüllt

    • Offizieller Beitrag

    Hi,
    ich habe das Problem mal auf folgende Funktion reduziert, in der der Fehler entsteht.
    Ich erstelle eine Struktur und befülle diese mit Werten. Die Struktur selbst wird als Pointer in einer anderen Struktur abgespeichert, ebenso der Struktur--String. Die Überprüfumg innerhalb der Funktion ist erfolgreich. Jedoch liefert dieselbe Überprüfung mit der zurückgegebenen Struktur fehlerhafte Werte. Jemand eine Idee warum?

  • Jedoch liefert dieselbe Überprüfung mit der zurückgegebenen Struktur fehlerhafte Werte.


    Was meinst du exakt mit "fehlerhafte Werte"?
    Die Ausgabe wirkt für mich nicht fehlerhaft:

    Ausgabe mit v.3.3.12.0 sowohl x64 als auch x86
    • Offizieller Beitrag

    Was meinst du exakt mit "fehlerhafte Werte"?

    Ist ja krass, ich bekomme folgende Ausgabe (reproduzierbar):

    Ich verwende auch die 3.3.12.0

  • Also, der Fehler versteckt sich in Zeile 9. Du deklarierst dort eine LOKALE Variable. Der Speicherplatz wird ja normalerweise beim Beenden der Funktion wieder freigegeben. Da du aber mit einen Pointer arbeitest und auf den freigegebenen Speicherplatz verweist, kann es sein dass der Speicher bereits schon mit neuen Werten überschrieben wurde. Das ist auch der Grund warum der Code bei AspirinJunkie scheinbar funktioniert, er hatte nur Glück bei der Ausführung, dass die Werte in dem Speicherbereich noch nicht überschrieben wurde. Abhilfe schafft hier eine statische lokale oder globale Variable. :)


    [autoit][/autoit][autoit][/autoit][autoit]

    $tRet = _SomeFunc()
    $tRetTime = DllStructCreate($tRet.tagTime, $tRet.Time)
    For $i = 1 To 6
    ConsoleWrite('Return ' & $i & ': ' & DllStructGetData($tRetTime, $i) & @CRLF)
    Next

    [/autoit][autoit][/autoit][autoit]

    Func _SomeFunc()
    Local $tagTime = 'char Year[4];char Month[2];char Day[2];char Hour[2];char Min[2];char Sec[2]'
    Local Static $tTime = DllStructCreate($tagTime)
    DllStructSetData($tTime, 'Year', @YEAR)
    DllStructSetData($tTime, 'Month', @MON)
    DllStructSetData($tTime, 'Day', @MDAY)
    DllStructSetData($tTime, 'Hour', @HOUR)
    DllStructSetData($tTime, 'Min', @MIN)
    DllStructSetData($tTime, 'Sec', @SEC)
    Local $t = DllStructCreate('struct;ptr Time;char tagTime[75];endstruct')
    DllStructSetData($t, 'Time', DllStructGetPtr($tTime))
    DllStructSetData($t, 'tagTime', $tagTime)

    [/autoit][autoit][/autoit][autoit]

    ; prüfen ob Struktur gefüllt und auslesbar
    Local $tCheck = DllStructCreate($t.tagTime, $t.Time)
    For $i = 1 To 6
    ConsoleWrite('Check Feld ' & $i & ': ' & DllStructGetData($tCheck, $i) & @CRLF)
    Next

    [/autoit][autoit][/autoit][autoit]

    Return $t
    EndFunc

    [/autoit][autoit][/autoit][autoit][/autoit]
  • Yo das isses.

    Zur Lösung würde ich zu HeapAlloc raten.
    Musst halt nur sicherstellen, dass du den allokierten Speicher immer wieder selbst mit HeapFree freigeben musst um keine Speicherleichen zu produzieren.

    Mal als Beispiel:

    Spoiler anzeigen
    • Offizieller Beitrag

    Zur Lösung würde ich zu HeapAlloc raten.

    Ist mit Sicherheit die sauberste Lösung. Für den von mir gewollten Zweck werde ich aber auf Local Static zurückgreifen. Zum Einen wird die Struktur u.U. mehrfach hintereinander genutzt und zum Anderen muß der User dann nicht dran denken den Speicher freizugeben.

    Danke noch mal.

    • Offizieller Beitrag

    Hallo,

    du weißt aber schon das du so nur eine Zeitangabe speichern kannst?

    Im obigen Beispiel sollte ja die Differenz zwischen Ret1 und Ret2 5 Sekunden betragen. Wie du aber in der Ausgabe siehst wird immer nur der letzte Zeitwert ausgeben, das liegt daran das du ja immer in den gleichen Speicherbereich schreibst.