Richtiges Nutzen von AllocateMemory()
Richtiges Nutzen von AllocateMemory()
Hallo allerseits,
Ich habe mal wieder eine Noob-Frage ...
Und zwar habe ich in meiner ganzen Zeit mit PureBasic noch kein einziges Mal den Befehl "AllocateMemory()" benutzt ... ergo weiß ich auch gar nicht, was dieser überhaupt tut, und wie man ihn zweckmäßig nutzt, und ob er für meine Zwecke überhaupt relevant ist; ich sehe ihn aber andauernd in Beispiel-Codes im Forum und anderswo. Die F1-Hilfe ist mir bei meiner Frage keine große Hilfe, die ist sehr abstrakt und allgemein gehalten. Irgendwie wird Speicher reserviert, okay. Aber wie, warum, wozu? Und warum komme ich "trotzdem" klar, auch ohne den Befehl zu verwenden?
Ist das Speicher allokieren evtl. nur in Kombination mit "Peek" und "Poke" sinnvoll (beide noch nie verwendet) ... ?
Grafik-, Sound- und File-Operationen führe ich in meinen Applikationen dagegen am laufenden Band durch, ich nutze Structures und Listen, Pointer, "pass by reference" und "PB-Any".
Aber irgendwie wurmt es mich schon, daß es da draußen ein weiteres Konzept gibt, daß ich ums Verrecken nicht verstehe, und was mir vielleicht dabei helfen könnte, noch effizienter und sauberer zu programmieren.
Vielen Dank!
Ich habe mal wieder eine Noob-Frage ...
Und zwar habe ich in meiner ganzen Zeit mit PureBasic noch kein einziges Mal den Befehl "AllocateMemory()" benutzt ... ergo weiß ich auch gar nicht, was dieser überhaupt tut, und wie man ihn zweckmäßig nutzt, und ob er für meine Zwecke überhaupt relevant ist; ich sehe ihn aber andauernd in Beispiel-Codes im Forum und anderswo. Die F1-Hilfe ist mir bei meiner Frage keine große Hilfe, die ist sehr abstrakt und allgemein gehalten. Irgendwie wird Speicher reserviert, okay. Aber wie, warum, wozu? Und warum komme ich "trotzdem" klar, auch ohne den Befehl zu verwenden?
Ist das Speicher allokieren evtl. nur in Kombination mit "Peek" und "Poke" sinnvoll (beide noch nie verwendet) ... ?
Grafik-, Sound- und File-Operationen führe ich in meinen Applikationen dagegen am laufenden Band durch, ich nutze Structures und Listen, Pointer, "pass by reference" und "PB-Any".
Aber irgendwie wurmt es mich schon, daß es da draußen ein weiteres Konzept gibt, daß ich ums Verrecken nicht verstehe, und was mir vielleicht dabei helfen könnte, noch effizienter und sauberer zu programmieren.
Vielen Dank!
Zuletzt geändert von diceman am 12.07.2019 11:48, insgesamt 1-mal geändert.
Now these points of data make a beautiful line,
And we're out of Beta, we're releasing on time.
And we're out of Beta, we're releasing on time.
- NicTheQuick
- Ein Admin
- Beiträge: 8679
- Registriert: 29.08.2004 20:20
- Computerausstattung: Ryzen 7 5800X, 32 GB DDR4-3200
Ubuntu 22.04.3 LTS
GeForce RTX 3080 Ti - Wohnort: Saarbrücken
- Kontaktdaten:
Re: Richtiges Nutzen von AllocateMemory()
Wie ist denn deine Erfahrung mit Pointern? Wozu nutzt du sie? Normalerweise nutzt man die häufig auf Speicherbereichen, die man mit AllocateMemory oder AllocateStructure alloziert hat.
Vielleicht ein einfaches Beispiel: Du kannst eine Datei öffnen, mit Lof() die Dateigröße bestimmen, dann mit AllocateMemory() entsprechend viel Speicher allozieren und dann mit ReadData() die gesamte Datei in diesen Speicherbereich laden. Dann hast du die gesamte Datei im RAM und kannst mit Peek, Poke oder mit Pointern in diesem Speicherbereich Daten lesen und ändern.
AllocateMemory() reserviert also entsprechend viel Speicher im RAM deines PCs, in den du beliebig schreiben und wieder lesen kannst.
Vielleicht ein einfaches Beispiel: Du kannst eine Datei öffnen, mit Lof() die Dateigröße bestimmen, dann mit AllocateMemory() entsprechend viel Speicher allozieren und dann mit ReadData() die gesamte Datei in diesen Speicherbereich laden. Dann hast du die gesamte Datei im RAM und kannst mit Peek, Poke oder mit Pointern in diesem Speicherbereich Daten lesen und ändern.
AllocateMemory() reserviert also entsprechend viel Speicher im RAM deines PCs, in den du beliebig schreiben und wieder lesen kannst.
Re: Richtiges Nutzen von AllocateMemory()
AllocateMemory() reserviert einen Speicher für die eigene Nutzung.
Du hast "Pointer" ja schon genutzt, vermutlich sowas wie @MeineVariable oder @MeineListe().
Das ist im Grunde schon das gleiche. Allerdings ist das ganze flüchtig.
Wenn man z.B. einem Gadget mehr Daten mitgeben möchte, ohne eine List() oder Map() zu benutzen,
kann man das nur über einen reservierten Speicherbereich machen, da ansonsten der Speicher nach beenden
einer Prozedur z.B. nicht mehr existiert, bzw. keinen definierten Wert mehr besitzt.
Damit kann man dann per SetGadgetData(Gadget, *Speicher) dem Gadget jede Menge Daten "anhängen".
Am besten mit einer Struktur, damit das ganze bequemer zu füllen und auszulesen ist.
Beispiele :
Wobei mittlerweile das AllocateMemory() in Verbindung mit einer Struktur nicht mehr genommen wird, sondern
AllocateStructure(), da es gleich das InitializeStructure mitmacht (das auch Listen/Maps und Strings richtig initialisiert)
und nebenbei Schreibarbeit spart
Du hast "Pointer" ja schon genutzt, vermutlich sowas wie @MeineVariable oder @MeineListe().
Das ist im Grunde schon das gleiche. Allerdings ist das ganze flüchtig.
Wenn man z.B. einem Gadget mehr Daten mitgeben möchte, ohne eine List() oder Map() zu benutzen,
kann man das nur über einen reservierten Speicherbereich machen, da ansonsten der Speicher nach beenden
einer Prozedur z.B. nicht mehr existiert, bzw. keinen definierten Wert mehr besitzt.
Damit kann man dann per SetGadgetData(Gadget, *Speicher) dem Gadget jede Menge Daten "anhängen".
Am besten mit einer Struktur, damit das ganze bequemer zu füllen und auszulesen ist.
Beispiele :
Code: Alles auswählen
Structure myGadget
Window.i
Font.i
Farbe.l
Flag.l
EndStructure
*Speicher.myGadget = AllocateMemory(SizeOf(myGadget))
*Speicher\Farbe = #Red
SetGadgetData(Gadget, *Speicher)
*Speicher = GetGadgetData(Gadget)
Debug *Speicher\Farbe
AllocateStructure(), da es gleich das InitializeStructure mitmacht (das auch Listen/Maps und Strings richtig initialisiert)
und nebenbei Schreibarbeit spart
PureBasic 6.10 LTS (Windows x86/x64) | Windows10 Pro x64 | Asus TUF X570 Gaming Plus | R9 5900X | 64GB RAM | GeForce RTX 3080 TI iChill X4 | HAF XF Evo | build by vannicom
Re: Richtiges Nutzen von AllocateMemory()
Ja vielen Dank, dann ist es doch schon etwas klarer geworden.
In der Tat nutze ich *pointer primär in Zusammenhang mit Listen; z.B. um Elemente miteinander zu vergleichen, oder nach einem erneuten ForEach-Aufruf innerhalb einer ForEach-Schleife den ursprünglichen Zustand der ersten ForEach-Schleife wieder herzustellen, etc. Da muß man natürlich hin und wieder aufpassen, daß man mit ChangeCurrentElement nicht versucht, ein gerade gelöschtes Element wieder herzstellen, sonst gibt's Schläge vom Compiler.
Ich habe eine prägende Blitzbasic-Vergangenheit, daher gehören Strukturen und Listen für mich zwangsläufig zusammen, bzw. sobald ich eine Struktur deklariert habe, initialisiere ich sogleich eine zugehörige Liste um evtl. erstellte Elemente ordentlich verwalten zu können (hier schlägt PureBasic BlitzBasic um Längen, was Tools angeht, und der damit entstehende kreativer Spielraum).
Dann weiß ich jetzt zumindest, daß ich nichts falsch mache, bzw. es auch anders geht.
Und sollte ich tatsächlich mal tatsächlich in die Situation kommen sollte, daß ich eine komplette Datei in den Speicher laden muß, weiß ich, was ich dafür tun muß.
In der Tat nutze ich *pointer primär in Zusammenhang mit Listen; z.B. um Elemente miteinander zu vergleichen, oder nach einem erneuten ForEach-Aufruf innerhalb einer ForEach-Schleife den ursprünglichen Zustand der ersten ForEach-Schleife wieder herzustellen, etc. Da muß man natürlich hin und wieder aufpassen, daß man mit ChangeCurrentElement nicht versucht, ein gerade gelöschtes Element wieder herzstellen, sonst gibt's Schläge vom Compiler.
Ich habe eine prägende Blitzbasic-Vergangenheit, daher gehören Strukturen und Listen für mich zwangsläufig zusammen, bzw. sobald ich eine Struktur deklariert habe, initialisiere ich sogleich eine zugehörige Liste um evtl. erstellte Elemente ordentlich verwalten zu können (hier schlägt PureBasic BlitzBasic um Längen, was Tools angeht, und der damit entstehende kreativer Spielraum).
Dann weiß ich jetzt zumindest, daß ich nichts falsch mache, bzw. es auch anders geht.
Und sollte ich tatsächlich mal tatsächlich in die Situation kommen sollte, daß ich eine komplette Datei in den Speicher laden muß, weiß ich, was ich dafür tun muß.
Zuletzt geändert von diceman am 12.07.2019 09:10, insgesamt 1-mal geändert.
Now these points of data make a beautiful line,
And we're out of Beta, we're releasing on time.
And we're out of Beta, we're releasing on time.
Re: Richtiges Nutzen von AllocateMemory()
Mit AllocateMemory() hast du die Möglichkeit, darauf zu reagieren, wenn der Speicher nicht reserviert werden konnte:Hier eine Variante ohne AllocateMemory():
Code: Alles auswählen
#KiB = 1024
#MiB = #KiB * 1024
#GiB = #MiB * 1024
*memory = AllocateMemory(40*#GiB)
If *memory
PokeB(*memory + 10, 22) ; Write test
FreeMemory(*memory)
Else
Debug "Fehler: Speicher konnte nicht reserviert werden!"
EndIf
Code: Alles auswählen
#KiB = 1024
#MiB = #KiB * 1024
#GiB = #MiB * 1024
; Wie bei AllocateMemory() reservieren wir 40 GigaByte RAM:
Dim memory.b(40*#GiB)
memory(10) = 22 ; Write test <= Ganzes Programm stürzt sofort ab!
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
- Imhotheb
- Beiträge: 192
- Registriert: 10.10.2014 13:14
- Computerausstattung: Intel 8086, 640 KB RAM, Hercules Video Adapter, 2 x 5 1/4" 360kb Floppy, MS-DOS 3
- Wohnort: Wolfenbüttel
Re: Richtiges Nutzen von AllocateMemory()
Gibt es bei Dim einen Max-Wert?
Weil das hier:korrekte 42949672960 ausgibt.
Dieser Code: aber nur 0.
Weil das hier:
Code: Alles auswählen
#KiB = 1024
#MiB = #KiB * 1024
#GiB = #MiB * 1024
*memory = AllocateMemory(40*#GiB)
If *memory
Debug MemorySize(*memory) ; 42949672960
FreeMemory(*memory)
Else
Debug "Fehler: Speicher konnte nicht reserviert werden!"
EndIf
Dieser Code:
Code: Alles auswählen
#KiB = 1024
#MiB = #KiB * 1024
#GiB = #MiB * 1024
; Wie bei AllocateMemory() reservieren wir 40 GigaByte RAM:
Dim memory.b(40*#GiB)
Debug ArraySize(memory()) ; 0 ... sollte auch 42949672960 sein
weil einfach einfach einfach ist ... mach' ich es anders
- TroaX
- Beiträge: 661
- Registriert: 08.03.2013 14:27
- Computerausstattung: PC: Ryzen 9 3950X, 96 GB RAM, RX6800XT, 2.5 TB SSD, 21:9 Display, Pop_OS! | Lappi: Ryzen 7 5800H, 16 GB RAM, 1 TB SSD, Pop_OS!
- Wohnort: NRW
- Kontaktdaten:
Re: Richtiges Nutzen von AllocateMemory()
Für AllocateMemory gibt es viele Gründe. Grundsätzlich ist die Beschreibung in der Hilfe genau das, wie es auch zu beschreiben ist. Man reserviert einen Zusammenhängenden Speicherbereich. Dies ist aus verschiedenen Gründen nötig. Zum einen kann man in dem Speicher alles an Daten ablegen. Zum anderen kann man jedes erdenkliche Byte aus diesem Bereich abrufen oder ändern.
Es kommt immer auch darauf an, was man macht. Ich verwende es relativ häufig. Zum Beispiel beim Webserver, bei dem man nie weiß, wie groß die übertragenen Daten sind oder welchem Typ sie angehören. Oder allgemein Netzwerkgeschichten. Ich vermeide es auch gerne. Aber oftmals kommt man auch einfach nicht drum herum.
Es kommt immer auch darauf an, was man macht. Ich verwende es relativ häufig. Zum Beispiel beim Webserver, bei dem man nie weiß, wie groß die übertragenen Daten sind oder welchem Typ sie angehören. Oder allgemein Netzwerkgeschichten. Ich vermeide es auch gerne. Aber oftmals kommt man auch einfach nicht drum herum.
PC: Ryzen 9 3950X | 96 GB RAM | RX6800XT | 2,5 TB NVMe | Pop_OS!
Notebook: 16" 3:2 | Ryzen 7 5800H | 16 GB RAM | Radeon Vega | 1TB NVMe | Pop_OS!
NAS: Fritz.Box
Coding: Purebasic 6.04 | PHP | HTML | CSS | Javascript
Notebook: 16" 3:2 | Ryzen 7 5800H | 16 GB RAM | Radeon Vega | 1TB NVMe | Pop_OS!
NAS: Fritz.Box
Coding: Purebasic 6.04 | PHP | HTML | CSS | Javascript
Re: Richtiges Nutzen von AllocateMemory()
Da man mit Pointer sich auch schnell vertun kann, hier eine Erweiterung im Debuggermodus
Code: Alles auswählen
;-TOP
;
; Memory Debugging v0.5
CompilerIf #PB_Compiler_Debugger
#MemoryStop = 1
Global NewMap MemID()
Procedure MyAllocateMemory(Size, Flags, Proc.s)
Protected *mem
*mem = AllocateMemory(Size, Flags)
If *mem
MemID(Hex(*mem)) = *mem
Else
CompilerIf #MemoryStop
If MessageRequester("AllocateMemory", "Out Of Memory : " + #LF$ + "Proc: " + Proc,
#PB_MessageRequester_YesNo | #PB_MessageRequester_Error) = #PB_MessageRequester_No
End
EndIf
CompilerElse
DebuggerWarning("FreeMemory: Out Of Memory : " + Proc)
CompilerEndIf
ProcedureReturn #False
EndIf
ProcedureReturn *mem
EndProcedure
Procedure MyFreeMemory(Memory, Proc.s)
If FindMapElement(MemID(), Hex(Memory))
FreeMemory(Memory)
DeleteMapElement(MemID())
ProcedureReturn #True
Else
CompilerIf #MemoryStop
If MessageRequester("FreeMemory", "Memory not exists : " + #LF$ + "Proc: " + Proc,
#PB_MessageRequester_YesNo | #PB_MessageRequester_Error) = #PB_MessageRequester_No
End
EndIf
CompilerElse
DebuggerWarning("FreeMemory: Memory not exists : " + Proc)
CompilerEndIf
ProcedureReturn #False
EndIf
EndProcedure
Procedure MyMemorySize(Memory, Proc.s)
If FindMapElement(MemID(), Hex(Memory))
ProcedureReturn MemorySize(Memory)
Else
CompilerIf #MemoryStop
If MessageRequester("MemorySize", "Memory not exists : " + #LF$ + "Proc: " + Proc,
#PB_MessageRequester_YesNo | #PB_MessageRequester_Error) = #PB_MessageRequester_No
End
EndIf
CompilerElse
DebuggerWarning("MemorySize: Memory not exists : " + Proc)
CompilerEndIf
ProcedureReturn 0
EndIf
EndProcedure
Macro AllocateMemory(Size, Flags=0)
MyAllocateMemory(Size, Flags, #PB_Compiler_Module + "/" + #PB_Compiler_Procedure + "() - Line " + #PB_Compiler_Line)
EndMacro
Macro FreeMemory(Memory)
MyFreeMemory(Memory, #PB_Compiler_Module + "/" + #PB_Compiler_Procedure + "() - Line " + #PB_Compiler_Line)
EndMacro
Macro MemorySize(Memory)
MyMemorySize(Memory, #PB_Compiler_Module + "/" + #PB_Compiler_Procedure + "() - Line " + #PB_Compiler_Line)
EndMacro
CompilerEndIf
;- test
Procedure Main()
*mem1 = AllocateMemory(1024)
;*mem2 = AllocateMemory(2048)
Debug "Size 1: " + MemorySize(*mem1)
Debug "Size 2: " + MemorySize(*mem2)
Debug "Free 1: " + FreeMemory(*mem1)
Debug "Free 2: " + FreeMemory(*mem2)
EndProcedure : main()
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Re: Richtiges Nutzen von AllocateMemory()
Danke für deine Mühe, den Code gucke ich mir nachher mal an.
Habe jetzt, glaube ich, selbst ein Beispiel gefunden, wo AllocateMemory() relevant für mich werden könnte, und zwar wenn ich mit ReceiveHTTPFile eine Seite aus dem Netz ziehe um diese z.B. nach Keywords zu durchforsten, müßte ich Speicher reservieren, in denen ich die Website-Daten ablegen kann, bevor ich irgend etwas Sinnvolles mit dem File anstellen kann ...
Habe jetzt, glaube ich, selbst ein Beispiel gefunden, wo AllocateMemory() relevant für mich werden könnte, und zwar wenn ich mit ReceiveHTTPFile eine Seite aus dem Netz ziehe um diese z.B. nach Keywords zu durchforsten, müßte ich Speicher reservieren, in denen ich die Website-Daten ablegen kann, bevor ich irgend etwas Sinnvolles mit dem File anstellen kann ...
Now these points of data make a beautiful line,
And we're out of Beta, we're releasing on time.
And we're out of Beta, we're releasing on time.