Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
_mem
#11
(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 ?
Steve never quite answered your question, so I can clarify this part Tongue

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).
Reply
#12
(01-01-2025, 10:45 AM)SMcNeill Wrote: Note: I *still* think we need a simple _MEMFREE option that frees all old blocks, just as CLOSE does all file handles.  Smile
I don't think that's a good idea. It reminds me of C++ where the requested memory is automatically released; as far as I can remember.

That's one of the reasons why, as I've read, many C programmers only use parts of C++. I myself have used it in C, where one don't want that values in memory deleted because one need them again in the rest of the program. This situation occurs much more often with a professional programmer.

Main conclusion: I don't think it's a good idea to release all memory blocks with just one command. Any reserved memory should only be released explicitly, as in C. That's part of the programmer's job . . . even if it "hurts".
Reply
#13
@Kernelpanic I somewhat disagree Tongue I think QB64 should have had entirely automatic memory management. We already partially have it, consider that variable length `String`s already get automatically allocated and cleaned up, it's not an issue. `_MEMNEW()` could have worked in a similar way - the memory could get cleaned up when there's no longer a way to access it, it just doesn't.

I do agree that a `_MEMFREE` command that frees every `_MEM` is a bad idea though. That's not a real memory management technique Big Grin It's an approach that stops working past a certain program size.
Reply




Users browsing this thread: 1 Guest(s)