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 :allright:
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)