Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
_mem
#1
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
Reply
#2
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.
Reply
#3
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
Reply
#4
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 ?
Reply
#5
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
Reply
#6
(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. Tongue )

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!
Reply
#7
Big Grin 
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 ?
Reply
#8
(01-01-2025, 10:27 AM)Jack Wrote: Big Grin 
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.  Wink
Reply
#9
Ok Steve, you win Big Grin
Reply
#10
Note: I *still* think we need a simple _MEMFREE option that frees all old blocks, just as CLOSE does all file handles.  Smile
Reply




Users browsing this thread: 2 Guest(s)