Author Topic: What to expect over the next 5 (or so) days...  (Read 4145 times)

Pete

  • Moderator
  • Hero Member
  • *****
  • Posts: 6240
  • Cuz I sez so varmint!
Re: What to expect over the next 5 (or so) days...
« Reply #30 on: April 20, 2012, 07:32:06 AM »
Will this development be of any use in tracking memory leaks?

In QB. you could use FRE(0), FRE(""), FRE(-1) to track how sub and recursive procedures were using memory.

Pete
It's only rocket science; it's not Linux!

Clippy

  • Hero Member
  • *****
  • Posts: 16431
  • I LOVE π = 4 * ATN(1)    Use the QB64 WIKI >>>
    • Pete's Qbasic Site
    • Email
Re: What to expect over the next 5 (or so) days...
« Reply #31 on: April 20, 2012, 08:02:23 AM »
I'd imagine that information would not be needed with current operating systems as they are not limited to 64K.

I would like to be able to SEE what I am doing instead of just tossing garbage into memory without a care in the world until something bad happens. How do I know that I am not taking memory from another process or reserved area? And I still don't see how it is any faster moving brain cells around rather than just thinking...

Why not create a MEMORY SYSTEM that does all of the dirty work FOR YOU? Does it SAFELY and is simple to use. I don't CARE where it puts it as long as it works. I don't even want to KNOW where it is as long as I can get back there when I need it. There are MILLIONS of places it could be! There are millions more where it can't be...

I believe those things are called variables...
« Last Edit: April 20, 2012, 09:13:00 AM by Clippy »
QB64 WIKI: Main Page
Download Q-Basics Code Demo: Q-Basics.zip
Download QB64 BAT, IconAdder and VBS shortcuts: QB64BAT.zip
Download QB64 DLL files in a ZIP: Program64.zip

Pete

  • Moderator
  • Hero Member
  • *****
  • Posts: 6240
  • Cuz I sez so varmint!
Re: What to expect over the next 5 (or so) days...
« Reply #32 on: April 20, 2012, 09:12:39 AM »
No worries. I used FRE() to illustrate a point. We don't need that statement anymore, but it was a tracking statement of memory, and I was wondering how this _MEM addition could be used in a similar way, and specifically if it would be useful in helping programmers track down memory leaks.

Pete
It's only rocket science; it's not Linux!

SMcNeill

  • Hero Member
  • *****
  • Posts: 2414
    • Email
Re: What to expect over the next 5 (or so) days...
« Reply #33 on: April 20, 2012, 12:11:39 PM »
Code: [Select]
DIM m AS _MEM
DIM f AS STRING * 5
m = _MEMNEW(5)
a = 12345
_MEMPUT m, m.OFFSET, a
_MEMGET m, m.OFFSET, b
PRINT b
c$ = "Doggy"
_MEMPUT m, m.OFFSET, c$
_MEMGET m, m.OFFSET, d$
_MEMGET m, m.OFFSET, f
e$ = _MEMGET(m, m.OFFSET, STRING * 5)
PRINT "d$ = ";d$
PRINT "e$ = ";e$
PRINT "f = ";f

So the above plays around with the new _MEM commands just a bit.

It's OK to put variable a into memory, and take variable b out of memory.
It puts variable c$ into memory, but it won't pull out d$.  It does give values for e$ and f. Is d$ considered invalid simply because it  has no set length?  Shouldn't it just take the whole block and put it into d$?  (Since we used m = _MEMNEW(5), there should only be 5 bytes for it to read from, correct?  Why wouldn't it just read all 5 of those and make it d$?)


Edit:   Was looking at the back posts, and was wondering about this as well:

"(ii) Allocating memory regions of various sizes which don't disappear when your SUB/FUNCTION exits
(iii) Allowing a program to pass any type of data to your SUB/FUNCTION (via a _MEM type) and working with that data (using m.TYPE) in an intelligent way"

Is there someway to define the area of memory which you use manually?  Or do you need to set a DIM SHARED mempointer, and then use it to keep up with the m.OFFSET which m = _MEMNEW(size) gives so that you can always keep up with the memory location easily?

Edit 2:  Does a CLEAR statement erase what we put in memory?  Or is it only erased through use of _MEMFREE m ?
« Last Edit: April 20, 2012, 12:54:28 PM by SMcNeill »
http://bit.ly/TextImage -- Library of QB64 code to manipulate text and images, as a BM library.
http://bit.ly/Color32 -- A set of color CONST for use in 32 bit mode, as a BI library.

http://bit.ly/DataToDrive - A set of routines to quickly and easily get data to and from the disk.  BI and BM files

Clippy

  • Hero Member
  • *****
  • Posts: 16431
  • I LOVE π = 4 * ATN(1)    Use the QB64 WIKI >>>
    • Pete's Qbasic Site
    • Email
Re: What to expect over the next 5 (or so) days...
« Reply #34 on: April 20, 2012, 03:33:13 PM »
Why can't _OFFSET be cast to a long value?

Code: [Select]
DIM a as _OFFSET
DIM b as LONG

b = a  'error in status

PRINT a

All of the other variable types can be cast. Why not _OFFSET?
QB64 WIKI: Main Page
Download Q-Basics Code Demo: Q-Basics.zip
Download QB64 BAT, IconAdder and VBS shortcuts: QB64BAT.zip
Download QB64 DLL files in a ZIP: Program64.zip

mcalkins

  • Hero Member
  • *****
  • Posts: 1269
    • qbasicmichael.com
    • Email
Re: What to expect over the next 5 (or so) days...
« Reply #35 on: April 20, 2012, 04:24:37 PM »
Quote from: Clippy on April 20, 2012, 03:33:13 PM
Why can't _OFFSET be cast to a long value?

Code: [Select]
DIM a as _OFFSET
DIM b as LONG

b = a  'error in status

PRINT a

All of the other variable types can be cast. Why not _OFFSET?

Good question. I don't see why you shouldn't be able to mix _OFFSETs and LONGs on 32 bit targets and _OFFSETs and _INTEGER64s on 64 bit targets.

A number of times, I've been saved by QB64 catching _OFFSET / integer mismatches. It's good for the compiler to catch accidental mistakes like that, but if you really want to convert, there should be a way, (something like an explicit cast).

You should be able to cast it already like this:

b = val("&h"+hex$(a))

But that's obviously not ideal.

Regards,
Michael
The QBASIC Forum Community: http://www.network54.com/index/10167 Includes off-topic subforums.
QB64 Off-topic subforum: http://qb64offtopic.freeforums.org/

Clippy

  • Hero Member
  • *****
  • Posts: 16431
  • I LOVE π = 4 * ATN(1)    Use the QB64 WIKI >>>
    • Pete's Qbasic Site
    • Email
Re: What to expect over the next 5 (or so) days...
« Reply #36 on: April 20, 2012, 09:31:34 PM »
I don't recall having this problem before so it may be something added for the _MEM stuff.

I figured that LONG would not be overflowed by _OFFSET values.
QB64 WIKI: Main Page
Download Q-Basics Code Demo: Q-Basics.zip
Download QB64 BAT, IconAdder and VBS shortcuts: QB64BAT.zip
Download QB64 DLL files in a ZIP: Program64.zip

Galleon

  • Administrator
  • Hero Member
  • *****
  • Posts: 4664
  • QB Forever
    • Email
Re: What to expect over the next 5 (or so) days...
« Reply #37 on: April 21, 2012, 12:45:28 AM »
Quote
So what ranges of values would each of the type values be?
    m.OFFSET (AS _OFFSET)
    m.SIZE (AS _OFFSET)
    m.TYPE (AS LONG)
    m.ELEMENTSIZE (AS _OFFSET)
The range of an _OFFSET type varies depending on the OS/platform.
Quote
How would the _MEM TYPE look if I made it myself.
There are also hidden values which are subject to change, so you cannot construct a _MEM type manually.

Quote
Will this development be of any use in tracking memory leaks?
No.
Quote
I was wondering how this _MEM addition could be used in a similar way, and specifically if it would be useful in helping programmers track down memory leaks.
It's an interesting thought that is worth following up on.

Quote
I would like to be able to SEE what I am doing instead of just tossing garbage into memory without a care in the world until something bad happens. How do I know that I am not taking memory from another process or reserved area?
Using the _MEM functions ensures that the blocks of memory you are using pertain only to the variables you passed or created. You cannot access memory from another process or reserved area.

Quote
And I still don't see how it is any faster moving brain cells around rather than just thinking...
DIM a(100,100) AS LONG
DIM b(100,100) AS LONG
Now, move the contents of array a to array b in the fastest way possible using QB64 code...
I hear you saying, then add a command to QB64 to do this... but there are 100s or 1000s of cases similar to this, cases where working with memory as blocks is simpler and faster.

Quote
It puts variable c$ into memory, but it won't pull out d$.  It does give values for e$ and f. Is d$ considered invalid simply because it  has no set length?  Shouldn't it just take the whole block and put it into d$?  (Since we used m = _MEMNEW(5), there should only be 5 bytes for it to read from, correct?  Why wouldn't it just read all 5 of those and make it d$?)
It's a good idea.
Quote
Is there someway to define the area of memory which you use manually?  Or do you need to set a DIM SHARED mempointer, and then use it to keep up with the m.OFFSET which m = _MEMNEW(size) gives so that you can always keep up with the memory location easily?
Exactly, you can make a shared array of _MEM references too or use STATIC m AS _MEM

Quote
Does a CLEAR statement erase what we put in memory?  Or is it only erased through use of _MEMFREE m ?
At present, no CLEAR does not erase mem blocks so you need to free them before calling clear. This needs to be reviewed, as well as the use of RUN.

Quote
Why can't _OFFSET be cast to a long value?
DIM a as _OFFSET
DIM b as LONG
b = a  'error in status
PRINT a
All of the other variable types can be cast. Why not _OFFSET?
An _OFFSET is system/OS dependent in size and designed to store memory offsets. On some systems a memory offset may not fit in a LONG, and on future systems it is possible that an _OFFSET wouldn't even fit in an _INTEGER64. As such, if a programmer stores an _OFFSET in any other type of variable that program has a high chance of not working in the future. That's why QB64 does everything it can (within reason) to dissuade you from performing such actions.

Quote
....Good question. I don't see why you shouldn't be able to mix _OFFSETs and LONGs on 32 bit targets and _OFFSETs and _INTEGER64s on 64 bit targets.
A number of times, I've been saved by QB64 catching _OFFSET / integer mismatches. It's good for the compiler to catch accidental mistakes like that, but if you really want to convert, there should be a way, (something like an explicit cast).
You should be able to cast it already like this:
b = val("&h"+hex$(a))
But that's obviously not ideal.
The fact that you don't see why it shouldn't be allowed is exactly why it isn't allowed. QB64 is future-proofing your program for you. And the less-than-ideal workaround you proposed is one of the ways you can circumvent that protection. Luckily, as a good programmer you also realize the performance cost involved. 8)

Quote
I don't recall having this problem before so it may be something added for the _MEM stuff.
I figured that LONG would not be overflowed by _OFFSET values.
No, it's been blocked since the implementation of the _OFFSET type.
« Last Edit: April 21, 2012, 03:28:23 AM by Galleon »
Something old... Something new... Something borrowed... Something blue...

Galleon

  • Administrator
  • Hero Member
  • *****
  • Posts: 4664
  • QB Forever
    • Email
Re: What to expect over the next 5 (or so) days...
« Reply #38 on: April 21, 2012, 03:28:35 AM »
[updated above reply]
Something old... Something new... Something borrowed... Something blue...

SMcNeill

  • Hero Member
  • *****
  • Posts: 2414
    • Email
Re: What to expect over the next 5 (or so) days...
« Reply #39 on: April 21, 2012, 04:15:46 AM »
Quote from: Galleon on April 21, 2012, 12:45:28 AM
Quote
Does a CLEAR statement erase what we put in memory?  Or is it only erased through use of _MEMFREE m ?
At present, no CLEAR does not erase mem blocks so you need to free them before calling clear. This needs to be reviewed, as well as the use of RUN.

Code: [Select]
CLS
DIM m AS _MEM
m = _MEMNEW(10)
DIM f AS STRING * 10
DIM g AS STRING * 10
f = "Test Junk"
_MEMPUT m, m.OFFSET, f
_MEMGET m, m.OFFSET, g
PRINT "We got our data ==> "; g
OPEN "temp.xyz" FOR OUTPUT AS #1
WRITE #1, m.OFFSET
CLOSE
PRINT m.OFFSET
'Wrote the mem location for retrieval, after a CLEAR
'Printed the location on the screen so we can be certain we're trying to fetch info from the same spot.

CLEAR


OPEN "temp.xyz" FOR INPUT AS #1
INPUT #1, x#
CLOSE
PRINT x#
PRINT "Do the 2 numbers above match (y/n)?"
DO
    a$ = INKEY$
LOOP UNTIL UCASE$(a$) = "Y" OR UCASE$(a$) = "N"
IF a$ = "N" THEN
    END 'We have a bug writing and retrieving the memory address
ELSE 'We got the right address back
    _MEMGET m, x#, f 'Now we try to access it, and the program stops.  MEMORY IS NOT INITIALIZED
    PRINT f
END IF
END

From what I've noticed playing around CLEAR does get rid of the memory.  Or at the very least it gets rid of the key which lets you access the memory. Once CLEAR is issued, I can't find anyway to access the memory once again.  (Which would be very useful if you could I'd think.  Seems there's always a few variables/bits of data which a person would love to keep even after CLEARing everything else.)  In the code above, the memory address is saved in a temp file, and retrieved after the CLEAR is issued.  Trying to use it to retrieve the data which was put in memory, simply leads us to a MEMORY NOT INITIALIZED error which halts the program.

If CLEAR is going to destroy the key to the memory, it needs to erase and free the memory as well.  Or if it's going to leave the memory intact, then they key to access it needs to stay valid.  Would there be a way to actually toggle between those 2 modes of CLEAR interaction?  Say a _MEMCLEAR = 1 for saving the data and access after a CLEAR, and a _MEMCLEAR = 0 to simply let CLEAR wipe the key and memory all by itself?
http://bit.ly/TextImage -- Library of QB64 code to manipulate text and images, as a BM library.
http://bit.ly/Color32 -- A set of color CONST for use in 32 bit mode, as a BI library.

http://bit.ly/DataToDrive - A set of routines to quickly and easily get data to and from the disk.  BI and BM files

chronokitsune

  • Guest
Re: What to expect over the next 5 (or so) days...
« Reply #40 on: April 21, 2012, 04:36:07 AM »
Quote from: Clippy on April 20, 2012, 09:31:34 PM
I don't recall having this problem before so it may be something added for the _MEM stuff.

I figured that LONG would not be overflowed by _OFFSET values.

You can get around it quite easily, but I wouldn't recommend it unless you mean for your code to only run on one platform.  Then again, you only care about Windblows anyway.  :P

Code: [Select]
DIM o AS _OFFSET
DIM ell AS _UNSIGNED LONG

o = &H100000000 'using 64-bit versions of QB64, this is 4294967296, but using 32-bit systems, it is 0
ell = VAL(STR$(o))
PRINT "Offset: "; o
PRINT "Long: "; ell

Just remember: it's your own fault if your value is wrong.  You won't run into this on Windows because the 64-bit version of QB64 doesn't exist yet, so _OFFSET is always a 32-bit value.  However, OS X and Linux will suffer, not that most programmers will care, especially as beginners!  Also remember that you're wasting an extra four bytes on a 32-bit system if you store it in an _UNSIGNED _INTEGER64 value, not to mention the extra overhead of mathematical operations for 64-bit integers on a 32-bit system.  So what's the fix?  Use the _OFFSET value as it is because otherwise you could cause problems, preventing your code from running on another system.

The following is an example that uses the system's C library.  The strpbrk() function is provided with a search string and a string of characters to search for.  The find_first_of%& function wraps this function up and will return the position of the first character in the given string, or 0 if not found or an error occurred (such as the supply of an empty string).  For example, if it returns 1, it would be the first character in the string.  Here's the code:
Code: [Select]
a$ = "Hello"
b$ = "lo"

i%& = find_first_of(a$, b$)
IF i%& = 0 THEN PRINT "No matches" ELSE PRINT MID$(a$, i%&)
END

FUNCTION find_first_of%& (haystack$, needles$)
    DECLARE LIBRARY
'Find the first character in x$ of the characters in y$.
FUNCTION strpbrk%& (x$, y$)
    END DECLARE
    find_first_of%& = strpbrk%&(haystack$, needles$)
    IF find_first_of%& <> 0 THEN
        'Strings are unit-based in QB64, so we must add 1.
        find_first_of%& = find_first_of%& - _OFFSET(haystack$) + 1
    END IF
END FUNCTION

Galleon

  • Administrator
  • Hero Member
  • *****
  • Posts: 4664
  • QB Forever
    • Email
Re: What to expect over the next 5 (or so) days...
« Reply #41 on: April 21, 2012, 05:04:50 AM »
Quote
Just remember: it's your own fault if your value is wrong.  You won't run into this on Windows because the 64-bit version of QB64 doesn't exist yet, so _OFFSET is always a 32-bit value.  However, OS X and Linux will suffer, not that most programmers will care, especially as beginners!  Also remember that you're wasting an extra four bytes on a 32-bit system if you store it in an _UNSIGNED _INTEGER64 value, not to mention the extra overhead of mathematical operations for 64-bit integers on a 32-bit system.  So what's the fix?  Use the _OFFSET value as it is because otherwise you could cause problems, preventing your code from running on another system.
Wise words there Chronokitsune. And when Windows ceases support for 32-bit (by which time there will of course be a 64-bit version of QB64[as well as a 64/32 cross-compilation option) people who circumvented the _OFFSET protection system to store these in LONGs will suffer regardless of whether they aimed for Linux compatibility or not. To add to your thoughts, I think people also have their head in the sand about 128-bit operating systems. 90% of technology purchasers have no idea about why 64bit is better than 32bit (and why it is not necessarily that much better ;)), they saw the new bigger number, they read about it and hear talk about it and they buy it. It'll be no different with 128-bit (because who'd want their 128-bit integer CPU calculations performed on a 64-bit processor anyway? :D)

Quote
From what I've noticed playing around CLEAR does get rid of the memory.  Or at the very least it gets rid of the key which lets you access the memory. Once CLEAR is issued, I can't find anyway to access the memory once again.  (Which would be very useful if you could I'd think.  Seems there's always a few variables/bits of data which a person would love to keep even after CLEARing everything else.)  In the code above, the memory address is saved in a temp file, and retrieved after the CLEAR is issued.  Trying to use it to retrieve the data which was put in memory, simply leads us to a MEMORY NOT INITIALIZED error which halts the program.

If CLEAR is going to destroy the key to the memory, it needs to erase and free the memory as well.  Or if it's going to leave the memory intact, then they key to access it needs to stay valid.  Would there be a way to actually toggle between those 2 modes of CLEAR interaction?  Say a _MEMCLEAR = 1 for saving the data and access after a CLEAR, and a _MEMCLEAR = 0 to simply let CLEAR wipe the key and memory all by itself?
I agree that CLEAR should also free the memory allocated by _MEMNEW etc.
My advice would be to avoid the use of the CLEAR command altogether, for a range of reasons.
« Last Edit: April 21, 2012, 05:22:57 AM by Galleon »
Something old... Something new... Something borrowed... Something blue...

Clippy

  • Hero Member
  • *****
  • Posts: 16431
  • I LOVE π = 4 * ATN(1)    Use the QB64 WIKI >>>
    • Pete's Qbasic Site
    • Email
Re: What to expect over the next 5 (or so) days...
« Reply #42 on: April 21, 2012, 06:13:00 AM »
Quote from: Galleon
An _OFFSET is system/OS dependent in size and designed to store memory offsets. On some systems a memory offset may not fit in a LONG, and on future systems it is possible that an _OFFSET wouldn't even fit in an _INTEGER64. As such, if a programmer stores an _OFFSET in any other type of variable that program has a high chance of not working in the future. That's why QB64 does everything it can (within reason) to dissuade you from performing such actions.

Dissuading is one thing, not allowing is another. Perhaps it is time to introduce the "Overflow" error. I know you have worked hard to avoid it, but in this case it might make sense. People are used to casting values from different TYPE values. Why stop it altogether.

Quote from: SMcNeill
If CLEAR is going to destroy the key to the memory, it needs to erase and free the memory as well.  Or if it's going to leave the memory intact, then they key to access it needs to stay valid.  Would there be a way to actually toggle between those 2 modes of CLEAR interaction?  Say a _MEMCLEAR = 1 for saving the data and access after a CLEAR, and a _MEMCLEAR = 0 to simply let CLEAR wipe the key and memory all by itself?

Wouldn't _MEMFREE do what you desire already? Couldn't it be incorporated into CLEAR Galleon? Or are we going to have a problem with memory blocks in use errors like we have with _FREEIMAGE?

BTW, this brings up another incompatibility. We have FREEFILE and _FREETIMER that return free files or timer numbers and we have _FREEIMAGE and _FREEFONT that actually free an image or font. Now we have _MEMFREE to free memory. Why not use _IMAGEFREE and _FONTFREE instead? Don't you think that this is kind of inconsistent? I do.

Then there is _SNDCLOSE ...  ;)
« Last Edit: April 21, 2012, 06:24:22 AM by Clippy »
QB64 WIKI: Main Page
Download Q-Basics Code Demo: Q-Basics.zip
Download QB64 BAT, IconAdder and VBS shortcuts: QB64BAT.zip
Download QB64 DLL files in a ZIP: Program64.zip

Galleon

  • Administrator
  • Hero Member
  • *****
  • Posts: 4664
  • QB Forever
    • Email
Re: What to expect over the next 5 (or so) days...
« Reply #43 on: April 21, 2012, 06:41:57 AM »
Quote
Dissuading is one thing, not allowing is another. Perhaps it is time to introduce the "Overflow" error. I know you have worked hard to avoid it, but in this case it might make sense. People are used to casting values from different TYPE values. Why stop it altogether.
For the reason you quoted. People who used 16-bit PEEK & POKE usually didn't fathom that their programs wouldn't work in 5 years time.

Quote
BTW, this brings up another incompatibility. We have FREEFILE and _FREETIMER that return free files or timer numbers and we have _FREEIMAGE and _FREEFONT that actually free an image or font. Now we have _MEMFREE to free memory. Why not use _IMAGEFREE and _FONTFREE instead? Don't you think that this is kind of inconsistent? I do.
It is a bit confusing, I agree. What do you propose we do about it?
Quote
Then there is _SNDCLOSE ...
Which closes a file which is potentially being streamed.
Something old... Something new... Something borrowed... Something blue...

Clippy

  • Hero Member
  • *****
  • Posts: 16431
  • I LOVE π = 4 * ATN(1)    Use the QB64 WIKI >>>
    • Pete's Qbasic Site
    • Email
Re: What to expect over the next 5 (or so) days...
« Reply #44 on: April 21, 2012, 06:56:37 AM »
At this point we could add the proper words and allow the others for backward compatiblity. I can just eliminate them over time by sending people to the new formats instead. I'll keep the old words in the lists and send them to the new formats.

This could be done relatively easy. Let me know what you want changed.

_SNDCLOSE also frees the sound handle value. Just tossed it in...  ;)
QB64 WIKI: Main Page
Download Q-Basics Code Demo: Q-Basics.zip
Download QB64 BAT, IconAdder and VBS shortcuts: QB64BAT.zip
Download QB64 DLL files in a ZIP: Program64.zip