(Pointer) Nie Pointer zu lokalen Variablen zurückgeben!
Verfasst: 22.05.2005 17:18
Ich habe das letztens in einem Code von Deeem2031 entdeckt. Er hat Pointer zu lokalen Variablen einer Procedure zurückgegeben, was in vielen Fällen zunächst mal kein Problem darstellt, wie man hier sieht:
Fügt man jetzt allerdings noch eine Zeile an, die neuen Speicher allokiert, sieht es so aus:Man könnte jetzt natürlich direkt den Wert der Procedure mit [c]PeekL()[/c] auslesen und in eine globale Variable lesen, was zunächst funktioniert:Aber in Zusammenhang mit Threads kann es durchaus passieren, dass in dieser einen Zeile, die ja trotzdem noch aus mehreren ASM-Befehlen besteht, die Speicherstelle, der die lokale Variable zugeordnet war, geändert wird, bevor [c]PeekL()[/c] den Wert ausgelesen und zurückgegeben hat.
Leider lässt sich dafür kein Code erfinden, der nach wenigen Sekunden Laufzeit direkt Fehler ausgibt. Aber im Grunde würde das dann so aussehen:
Code: Alles auswählen
Procedure.l pGetValue()
Protected a.l
a = 123
ProcedureReturn @a
EndProcedure
*a.LONG = pGetValue()
Debug *a\l
Code: Alles auswählen
Procedure.l pGetValue()
Protected a.l
a = 123
ProcedureReturn @a
EndProcedure
*a.LONG = pGetValue()
Debug *a\l
Dim b.l(1)
Debug *a\l
Code: Alles auswählen
Procedure.l pGetValue()
Protected a.l
a = 123
ProcedureReturn @a
EndProcedure
a.l = PeekL(pGetValue())
Debug a
Dim b.l(1)
Debug a
Leider lässt sich dafür kein Code erfinden, der nach wenigen Sekunden Laufzeit direkt Fehler ausgibt. Aber im Grunde würde das dann so aussehen:
Code: Alles auswählen
Procedure Thread(a.l)
Repeat
Dim b.l(Random(10))
ForEver
EndProcedure
Procedure.l pGetValue()
Protected a.l
a = 123
ProcedureReturn @a
EndProcedure
hT.l = CreateThread(@Thread(), 0)
For a.l = 1 To 1000
a.l = PeekL(pGetValue())
If a <> 123 : Debug a : EndIf
Next
KillThread(hT)