Posts: 434
Threads: 29
Joined: Apr 2022
Reputation:
30
12-31-2024, 09:52 PM
(This post was last modified: 12-31-2024, 09:54 PM by Jack.)
is the following program kosher ?
there should be no need for _MEMFREE , right ?
Code: (Select All)
Dim m As _MEM
Dim As Long i
Dim As Double x, y
Dim As String * 80 s
m = _Mem(s)
For i = 0 To 9
x = Sqr(i + 1)
_MemPut m, m.OFFSET + 8 * i, x
Next
For i = 0 To 9
_MemGet m, m.OFFSET + 8 * i, y
Print y
Next
Posts: 289
Threads: 6
Joined: Apr 2022
Reputation:
45
It depends somewhat what you're asking:
1. If you mean that program in it's entirety, then yes it's fine because you're not required to free anything before your program ends, the OS will do it if you don't.
2. If you mean using that as part of a larger program, then the requirement right now is that you `_MemFree` any `_Mem` that you receive, so `_Mem(variable)`, `_Mem(offset, length)`, `_MemImage(image)`, etc. all require calling `_MemFree`. Not doing so risks a memory leak related to the information used to track the `_Mem`s.
In practice `_Mem(variable)` does not actually require a `_MemFree` call, but it may not remain that way in the future so you should free them anyway.
Posts: 434
Threads: 29
Joined: Apr 2022
Reputation:
30
thanks DSMan195276
I think that I misunderstood the way _mem works, I thought that it worked similar to the following
Code: (Select All)
Declare CustomType Library
Sub memcpy (ByVal dest As _Offset, ByVal source As _Offset, ByVal bytes As Long)
End Declare
Dim As _Offset os, ox, oy
Dim As Long i
Dim As Double x, y
Dim As String * 80 s
os = _Offset(s)
ox = _Offset(x)
oy = _Offset(y)
For i = 0 To 9
x = Sqr(i + 1)
memcpy os, ox, 8
os = os + 8
Next
os = _Offset(s)
For i = 0 To 9
memcpy oy, os, 8
Print y
os = os + 8
Next
Posts: 434
Threads: 29
Joined: Apr 2022
Reputation:
30
regarding _Mem, run the following snippet
Code: (Select All)
Dim m As _MEM
Dim As Long i
Dim As _Byte ascii
Dim As String * 80 s
m = _Mem(s)
For i = 0 To 79
ascii = 33 + i
_MemPut m, m.OFFSET + i, ascii
Next
Print s
it's clear that the memory allocated to the string s is being addressed, so why do I need to free m which behaves as a pointer to s ?
Posts: 2,736
Threads: 331
Joined: Apr 2022
Reputation:
227
Here you go @Jack -- an example with two different mem methods to do what you're doing.
Code: (Select All)
Declare CustomType Library
Sub memcpy (ByVal dest As _Offset, ByVal source As _Offset, ByVal bytes As Long)
End Declare
Dim As _Offset os, ox, oy
Dim As Long i
Dim As Double x, y
Dim As String * 80 s
os = _Offset(s)
ox = _Offset(x)
oy = _Offset(y)
For i = 0 To 9
x = Sqr(i + 1)
memcpy os, ox, 8
os = os + 8
Next
os = _Offset(s)
For i = 0 To 9
memcpy oy, os, 8
Print y
os = os + 8
Next
Sleep
'Using _MEM commands instead
Print
Print "MEMCOPY!"
Dim As Double y1
Dim As _MEM m, m1
m = _Mem(s)
m1 = _Mem(y1)
's is already full of the data, so we don't need to recreate it. Let's just copy it to y1
For i = 0 To 9
_MemCopy m, m.OFFSET + i * 8, 8 To m1, m1.OFFSET
Print y1
Next
Sleep
Print
Print "MEMGET!"
For i = 0 To 9
Print _MemGet(m, m.OFFSET + i * 8, Double)
Next
Posts: 2,736
Threads: 331
Joined: Apr 2022
Reputation:
227
(01-01-2025, 10:01 AM)Jack Wrote: it's clear that the memory allocated to the string s is being addressed, so why do I need to free m which behaves as a pointer to s ?
Because m, itself, is really nothing more than a handle of sorts (unless used with _MEMNEW), and just like _LOADIMAGE creates handles endlessly, _MEM will as well. In the case of mem, each handle uses ... umm.. I'd guess 100 bytes of memory? (I'd have to look at the types and such to be certain, so let's just sy it's a hundred bytes at 5 in the morning and call it close enough. )
So inside a loop where you call something like:
SUB foo (x AS LONG)
DIM m AS _MEM
m = _MEM(x)
END SUB
That is going to use 100 bytes every time its called to create that handle with all its reference info, and you're never going to be able to free it until the program ends.
Call it a thousand times, you now have 100,000 bytes of memory tied up doing nothing that you can never free... Call it inside a game loop which repeats 60 times a second, and what's going to happen to your memory usage after 4 hours of playing the same game?
KABOOM!! Out of memory!
Posts: 434
Threads: 29
Joined: Apr 2022
Reputation:
30
Ok, I get what you are saying but it makes no sense, even if _MEM is a structure why is it not freed automatically just like a udt ?
Posts: 2,736
Threads: 331
Joined: Apr 2022
Reputation:
227
(01-01-2025, 10:27 AM)Jack Wrote:
Ok, I get what you are saying but it makes no sense, even if _MEM is a structure why is it not freed automatically just like a udt ?
Mem is set up very similar to OPEN file$ FOR BINARY..
Think of this:
Code: (Select All)
Do
foo
Loop Until _KeyHit
Sub foo
f = FreeFile
Open "temp.txt" For Binary As #f
Print f
End Sub
Now, without a CLOSE statement, the above is going to also be a memory leak. f is going to always increase handles for that file, and eventually you're going to run into issues somewhere.
Of course, it'll all close when the program closes, but if you want to prevent memory leaking, close it when you're done with it. There's no logic attached to do it automagically for you.
Posts: 434
Threads: 29
Joined: Apr 2022
Reputation:
30
Ok Steve, you win
Posts: 2,736
Threads: 331
Joined: Apr 2022
Reputation:
227
Note: I *still* think we need a simple _MEMFREE option that frees all old blocks, just as CLOSE does all file handles.
|