Struktur freigeben ?

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
silbersurfer
Beiträge: 175
Registriert: 06.07.2014 12:21

Struktur freigeben ?

Beitrag 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
Intel Quad Core 3,2 Ghz - GTX 1060 - BlitzBasic Plus 1.48 , PureBasic 5.70 LTS / Aktuelles Projekt PureCommander
Benutzeravatar
Sicro
Beiträge: 964
Registriert: 11.08.2005 19:08
Kontaktdaten:

Re: Struktur freigeben ?

Beitrag 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
Bild
Warum OpenSource eine Lizenz haben sollte :: PB-CodeArchiv-Rebirth :: Pleasant-Dark (Syntax-Farbschema) :: RegEx-Engine (kompiliert RegExes zu NFA/DFA)
Manjaro Xfce x64 (Hauptsystem) :: Windows 10 Home (VirtualBox) :: Neueste PureBasic-Version
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: Struktur freigeben ?

Beitrag 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.
Benutzeravatar
silbersurfer
Beiträge: 175
Registriert: 06.07.2014 12:21

Re: Struktur freigeben ?

Beitrag 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)
Intel Quad Core 3,2 Ghz - GTX 1060 - BlitzBasic Plus 1.48 , PureBasic 5.70 LTS / Aktuelles Projekt PureCommander
Benutzeravatar
Sicro
Beiträge: 964
Registriert: 11.08.2005 19:08
Kontaktdaten:

Re: Struktur freigeben ?

Beitrag 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. [...]
Bild
Warum OpenSource eine Lizenz haben sollte :: PB-CodeArchiv-Rebirth :: Pleasant-Dark (Syntax-Farbschema) :: RegEx-Engine (kompiliert RegExes zu NFA/DFA)
Manjaro Xfce x64 (Hauptsystem) :: Windows 10 Home (VirtualBox) :: Neueste PureBasic-Version
Benutzeravatar
silbersurfer
Beiträge: 175
Registriert: 06.07.2014 12:21

Re: Struktur freigeben ?

Beitrag 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
Intel Quad Core 3,2 Ghz - GTX 1060 - BlitzBasic Plus 1.48 , PureBasic 5.70 LTS / Aktuelles Projekt PureCommander
Benutzeravatar
Sicro
Beiträge: 964
Registriert: 11.08.2005 19:08
Kontaktdaten:

Re: Struktur freigeben ?

Beitrag 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)
Bild
Warum OpenSource eine Lizenz haben sollte :: PB-CodeArchiv-Rebirth :: Pleasant-Dark (Syntax-Farbschema) :: RegEx-Engine (kompiliert RegExes zu NFA/DFA)
Manjaro Xfce x64 (Hauptsystem) :: Windows 10 Home (VirtualBox) :: Neueste PureBasic-Version
Benutzeravatar
silbersurfer
Beiträge: 175
Registriert: 06.07.2014 12:21

Re: Struktur freigeben ?

Beitrag von silbersurfer »

Jo danke Sicro,

Damit kann Ich was anfangen, werde das gleich mal testen...
Intel Quad Core 3,2 Ghz - GTX 1060 - BlitzBasic Plus 1.48 , PureBasic 5.70 LTS / Aktuelles Projekt PureCommander
Benutzeravatar
mk-soft
Beiträge: 3855
Registriert: 24.11.2004 13:12
Wohnort: Germany

Re: Struktur freigeben ?

Beitrag 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)
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Antworten