Seite 1 von 1
Struktur freigeben ?
Verfasst: 13.03.2015 19:09
von silbersurfer
Hallo Leute
Mal eine kleine Frage bezüglich Strukturen.
Warum kann Ich nach freigeben der Struktur mit FreeMemory immer noch auf diese zugreifen
oder verstehe Ich da was ganz falsch.
Hier in diesem Beispiel kann ich immer noch auf die Struktur zugreifen aber dort kommen dann, Wilde Ergebnisse
Ich dachte das dann alles auf null gesetzt wird, oder kein zugriff mehr möglich ist.
Wäre nicht schlecht wenn einer mir das erklären könnte
Gruß Slibersurfer
Code: Alles auswählen
EnableExplicit
Structure Test
Testid.i
x.i
y.i
EndStructure
Procedure newTest()
Protected *this.test=AllocateMemory(SizeOf(test))
If (Not *this) : ProcedureReturn #False : EndIf
With *this
\Testid =1
\x =10
\y =20
EndWith
ProcedureReturn *this
EndProcedure
Procedure FreeTest(*free.test)
FreeMemory(*free)
EndProcedure
Define *test.test
*test=newtest()
freetest(*test)
Debug *test\Testid
Debug *test\x
Debug *test\y
Re: Struktur freigeben ?
Verfasst: 13.03.2015 19:36
von Sicro
Mit FreeMemory() wird dem Betriebssystem mitgeteilt, dass der zuvor per AllocateMemory() reservierte Speicherbereich wieder freigegeben werden soll. Der Pointer (*this) verweist aber weiterhin auf diesen Speicherbereich, weil du der Pointer-Variable (*this) ja kein neuen Wert zuweist - FreeMemory() macht das nicht. Wenn du also nach dem FreeMemory() weiterhin auf den Speicherbereich zugreifst, können die Daten schon von einem anderem Programm überschrieben sein, weil dieser nun den Speicher reserviert hat.
Hier ist übrigens das Strukturieren der Variable unnötig, da du sie hier gar nicht anwendest:
Code: Alles auswählen
Procedure FreeTest(*free.test)
FreeMemory(*free)
EndProcedure
Re: Struktur freigeben ?
Verfasst: 13.03.2015 19:45
von NicTheQuick
Mittlerweile gibt es übrigens auch 'AllocateStructure()' und 'FreeStructure()'. Damit entfällt dann der Aufruf von 'InitializeStructure()' bzw. 'ClearStructure()'', falls man dynamische Elemente innerhalb der Struktur hat.
Und ob man nun einen Pointer strukturiert, selbst wenn die Struktur nicht benutzt wird, ändert am kompilierten Ergebnis nichts. Meiner Meinung nach gehört es aber zum guten Stil einem Pointer den Datentyp zu geben, auf den er zeigt.
Re: Struktur freigeben ?
Verfasst: 13.03.2015 20:25
von silbersurfer
erstmal wieder danke für die schnellen Antworten hier.
Sicro schrieb
silbersurfer hat geschrieben:Hier ist übrigens das Strukturieren der Variable unnötig, da du sie hier gar nicht anwendest:
das habe Ich mir jetzt so angewöhnt, zumal Ich mit dem selben Pointer ja auch auf meine Struktur verweise.
Sicro dann müßte meine FreeTest Procedure demnach so aussehen üder?
Code: Alles auswählen
Procedure FreeTest(*free.test)
FreeMemory(*free)
ClearStructure(*free, test)
EndProcedure
NicTheQuick schrieb
Damit entfällt dann der Aufruf von 'InitializeStructure()' bzw. 'ClearStructure()'', falls man dynamische Elemente innerhalb der Struktur hat.
Nic das Beispiel aus der Hilfe zeigt das man clearStrcuture auch ohne Dynamische Felder zum löschen nimmt
also was macht er dann genau, löscht er nur die einträge oder gibt er auch den Speicher zuvor frei ?
Code: Alles auswählen
Structure People
Name$
LastName$
Age.l
EndStructure
Student.People\Name$ = "Paul"
Student\LastName$ = "Morito"
Student\Age = 10
ClearStructure(@Student, People)
Re: Struktur freigeben ?
Verfasst: 13.03.2015 20:53
von Sicro
NicTheQuick hat geschrieben:Und ob man nun einen Pointer strukturiert, selbst wenn die Struktur nicht benutzt wird, ändert am kompilierten Ergebnis nichts.
Ja, das stimmt. Im kompiliertem Ergebnis sind nur noch die anhand der Struktur ausgerechneten Offsets vorhanden. Wenn kein Zugriff eines Feldes der Struktur im Code stattfindet, wird die Struktur ignoriert.
NicTheQuick hat geschrieben:Meiner Meinung nach gehört es aber zum guten Stil einem Pointer den Datentyp zu geben, auf den er zeigt.
Ok, ich korrigiere meine Aussage zu: unnötig, aber empfehlenswert
silbersurfer hat geschrieben:Sicro dann müßte meine FreeTest Procedure demnach so aussehen üder?
Code: Alles auswählen
Procedure FreeTest(*free.test)
FreeMemory(*free)
ClearStructure(*free, test)
EndProcedure
Besser wäre es, wenn du den Pointer danach nicht mehr verwendest. AllocateMemory() nullt den Speicherbereich standardmäßig selber. Zudem ist es wahrscheinlich, dass du beim erneuten Allozieren ein ganz anderen Speicherbereich zugeteilt bekommst.
silbersurfer hat geschrieben:Nic das Beispiel aus der Hilfe zeigt das man clearStrcuture auch ohne Dynamische Felder zum löschen nimmt
also was macht er dann genau, löscht er nur die einträge oder gibt er auch den Speicher zuvor frei ?
Auszug aus PB-Hilfe zu ClearStruktur():
[...] gibt den Speicher eines strukturierten Speicherbereichs frei. [...] Alle Felder werden auf Null gesetzt. [...]
Re: Struktur freigeben ?
Verfasst: 13.03.2015 21:40
von silbersurfer
Jo danke Sirco,
Sicro hat geschrieben:Besser wäre es, wenn du den Pointer danach nicht mehr verwendest. AllocateMemory() nullt den Speicherbereich standardmäßig selber. Zudem ist es wahrscheinlich, dass du beim erneuten Allozieren ein ganz anderen Speicherbereich zugeteilt bekommst.
Wenn Ich aber mehre Procedure habe wo dieser Pointer darauf zugreift z.b
Code: Alles auswählen
EnableExplicit
Structure Test
Testid.i
x.i
y.i
EndStructure
Procedure newTest()
Protected *this.test=AllocateMemory(SizeOf(test))
If (Not *this) : ProcedureReturn #False : EndIf
With *this
\Testid =1
\x =10
\y =20
EndWith
ProcedureReturn *this
EndProcedure
Procedure SchreibeWas(gadget,*schreibe.test)
Debug *schreibe\Testid
Debug *schreibe\x
Debug *schreibe\y
EndProcedure
Procedure FreeTest(*free.test)
FreeMemory(*free)
ClearStructure(*free, test)
ProcedureReturn #False
EndProcedure
Define *test.test
*test=newtest()
freetest(*test)
schreibeWas(1,*test)
Dann muß Ich doch den Pointer so erhalten, damit es nicht zu Fehlermeldung kommt.
Oder wie meinst du das sonst, es wäre schön wenn Du einen Codeschnipsel von Dir Postest der das verdeutlicht
Re: Struktur freigeben ?
Verfasst: 14.03.2015 01:23
von Sicro
Code: Alles auswählen
EnableExplicit
Structure Test
Testid.i
x.i
y.i
EndStructure
Procedure newTest()
Protected *this.test=AllocateMemory(SizeOf(test))
If (Not *this) : ProcedureReturn #False : EndIf
With *this
\Testid =1
\x =10
\y =20
EndWith
ProcedureReturn *this
EndProcedure
Procedure SchreibeWas(gadget,*schreibe.test)
If *schreibe ; Ist der Pointer was anderes als Null?
Debug *schreibe\Testid
Debug *schreibe\x
Debug *schreibe\y
EndIf
EndProcedure
Procedure FreeTest(*free.test)
FreeMemory(PeekI(*free)) ; Per PeekI() den Pointer ermitteln und den Speicher, auf den der Pointer zeigt, freigeben.
;ClearStructure(*free, test)
PokeI(*free, 0) ; Den Pointer auf die Adresse Null setzen
ProcedureReturn #False
EndProcedure
Define *test.test
*test=newtest()
freetest(@*test) ; Adresse von der Pointer-Variable übergeben
Debug *test
schreibeWas(1,*test)
Re: Struktur freigeben ?
Verfasst: 14.03.2015 02:16
von silbersurfer
Jo danke Sicro,
Damit kann Ich was anfangen, werde das gleich mal testen...
Re: Struktur freigeben ?
Verfasst: 14.03.2015 03:47
von mk-soft
Besser so...
Code: Alles auswählen
Structure udtTest
ref.i
Testid.i
x.i
y.i
EndStructure
Procedure new()
Protected *result.udtTest
*result = AllocateMemory(SizeOf(udtTest))
If *result
*result\ref = 1
EndIf
ProcedureReturn *result
EndProcedure
Procedure addref(*this.udtTest)
If *this
*this\ref + 1
ProcedureReturn *this\ref
Else
ProcedureReturn 0
EndIf
EndProcedure
Procedure _release(*pp_this.integer)
Protected *this.udtTest
*this = *pp_this\i
If *this
*this\ref - 1
If *this\ref <= 0
FreeMemory(*this)
*pp_this\i = 0
ProcedureReturn 0
Else
ProcedureReturn *this\ref
EndIf
Else
ProcedureReturn 0
EndIf
EndProcedure
Macro release(this)
_release(@this)
EndMacro
*obj = new()
Debug "Object: " + Str(*obj)
Debug "AddRef: " + Str(addref(*obj))
Debug "AddRef: " + Str(addref(*obj))
Debug "Release: " + Str(release(*obj))
Debug "Object: " + Str(*obj)
Debug "Release: " + Str(release(*obj))
Debug "Object: " + Str(*obj)
Debug "Release: " + Str(release(*obj))
Debug "Object: " + Str(*obj)
Debug "Release: " + Str(release(*obj))
Debug "Object: " + Str(*obj)
Debug "Release: " + Str(release(*obj))
Debug "Object: " + Str(*obj)
Debug "Release: " + Str(release(*obj))
Debug "Object: " + Str(*obj)
Debug "Release: " + Str(release(*obj))
Debug "Object: " + Str(*obj)