01-01-2025, 11:13 PM
(01-01-2025, 10:27 AM)Jack Wrote:Steve never quite answered your question, so I can clarify this part
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 ?
Like you're thinking, the `_MEM` variable itself is free'd when it goes out of scope, like any other variable. The issue is that the UDT is not the only part of the `_MEM`, even when using `_MEM(variable)` the UDT contains a pointer to an internal structure maintained by the QB64 runtime. This structure tracks the validity of the `_MEM`, preventing you from using a copy of the `_MEM` after it has been free'd (or its reference goes out of scope, etc.). For example, look at this code:
Code: (Select All)
Dim m1 As _Mem, m2 as _Mem
m1 = _MemNew(20)
m2 = m1
_MemFree m1
_MemPut m2, m2.OFFSET, 0 As _BYTE
That gives an error "Memory has been freed" - calling `_MemFree` on `m1` invalidates all the copies of the `_Mem` UDT, such as `m2`. This works by marking the `_MEM` as invalid in the internal structure - when `m2` was copied it also got a copy of the pointer to the same internal structure and is thus marked invalid as well.
All `_MEM`s maintain that internal pointer to a structure, so you need to call `_MemFree` on them to release that structure even if the memory pointed at by the `_MEM` doesn't need to be free'd (because it's owned by something else, like an image or another variable).
On that note though, the internal structure can get released by some other approaches, so in practice you do not actually need to `_MemFree` every `_MEM`. We don't document these specifics though, so at the moment you shouldn't rely on it. But for example, when you use `_FREEIMAGE`, the `_MEM`s created from that image via `_MEMIMAGE()` also get free'd. `_MEM(variable)` is tied to the scope it is created in, so it get invalided automatically at the end of that scope (sub/function).