Day 026: ERASE
#1
ERASE probably should be renamed ARRase, because all it erases is the values stored in a specified array.

ERRASE makes the strings assigned to an array null or makes the numeric values assigned to a numeric array zero.

ERASE ArrayName [, others...]

Example:

Code: (Select All)
DIM Pete(10) AS STRING, var(100) AS INTEGER, cnt(20) AS LONG
ERASE Pete, var, cnt

ERASE can be used with STATIC or DYNAMIC arrays, but there is an important difference. Try running the two following code snippets. 

Code: (Select All)
DIM Pete(1 TO 20) AS INTEGER ' DIM makes Pete a STATIC array.
FOR i = 1 TO 20
    Pete(i) = -i
NEXT

FOR i = 1 TO UBOUND(Pete)
    PRINT Pete(i)
NEXT
SLEEP

ERASE Pete

' All zeros will now be output.
CLS
FOR i = 1 TO 20
    PRINT Pete(i)
NEXT
PRINT " ubound(Pete) is still ="; UBOUND(Pete)
Pete(15) = 101
PRINT: PRINT " Pete(15) ="; Pete(15)

Note: This routine will error out unless we Re-initialize the Pete array.
Code: (Select All)
REDIM Pete(1 TO 20) AS INTEGER ' REDIM makes Pete a DYNAMIC array.
FOR i = 1 TO 20
    Pete(i) = -i
NEXT

FOR i = 1 TO UBOUND(Pete)
    PRINT Pete(i)
NEXT
SLEEP

ERASE Pete

' This will error out unless we do a REDIM Pete(1 TO 20) here.
CLS
FOR i = 1 TO 20
    PRINT Pete(i)
NEXT
PRINT " ubound(Pete) is still ="; UBOUND(Pete)
Pete(15) = 101
PRINT: PRINT " Pete(15) ="; Pete(15)

So ERASE appears to have more value and versatility when used with STATIC arrays, if you consider not de-initialing your array as a benefit.

And what makes an array either static or dynamic? Well...

DIM makes the array static.

REDIM makes the array dynamic

And this important note...

REM $DYNAMIC makes ALL arrays dynamic. So even...

Code: (Select All)
REM $DYNAMIC
DIM Pete(1 to 20)
ERASE Pete
REDIM Pete(1 to 20)

...makes the otherwise static DIM array, of Pete, dynamic. So if you use REM $DYNAMIC at the top of your code, use REDIM because a DIM statement after an ERASE statement won't work with REM DYNAMIC in your code.

REM $STATIC makes ALL arrays static. but...

Code: (Select All)
REM $STATIC
REDIM Pete(1 to 20) ' Change to DIM to get this to work.
ERASE Pete
PRINT Pete(15) ' Errors out because even though we used REM $STATIC REDIM messed it up.

So we've kicked the tires quite a bit here. Anyone want to add anything more?

Pete
Reply
#2
This is one keyword where a lot of people tripped hard, coming from interpreted BASIC. Then after they got comfortable using "dynamic" arrays M$ BASIC PDS offered the "PRESERVE" clause to "REDIM" so that it was abused. Have to watch out for those memory leaks in older programs.

It's OK to use dynamic arrays inside a subprogram as long as its memory is released when the subprogram exits. Sometimes it can't be helped, such as needing to pass an array as parameter for a function, for example that builds a file list. In that case "ERASE" may not be used inside that subprogram, and it may not be used except if the programmer is extra sure at a certain point in the code that the array will no longer be used. The problem is that this programming language makes it so easy to create a static array, which could gobble up RAM, which causes a programmer to expect a dynamic array to behave the same way.

I wish "ERASE" mechanism were unified with those that free "_MEM" variables, font handles, image handles, sound handles and other things needing a specific "FREE" statement. Due to bad experiences in the past with "_FREEFONT" and the like, if I were as good as Galleon was coding in C++ I would fork QB64 to support this, although other things are top priority such as putting "PRING USING" output into a string...

I may or may not know what I'm talking about today.
Reply
#3
Quote:It's OK to use dynamic arrays inside a subprogram as long as its memory is released when the subprogram exits.

What? Isn't it released automatically when leave routine? assuming it was made in same.

Quote:I may or may not know what I'm talking about today.

Hmm...
b = b + ...
Reply
#4
> I may or may not know what I'm talking about today.

Dammit! I was just about to use that as my signature. Now I have to come up with something else. Too bad Steve is busy! Big Grin

Yes, there is some interesting behavior in subs. For example...

Code: (Select All)
CALL pete

a(5) = 7
PRINT "a(5) back in main:"; a(5) ' This works. An un-passed un-shared dynamic array in a sub had the initialization maintained.

REDIM b(10) ' Dynamic array in the main.
b(5) = 3
PRINT "b(5) in Pete sub:"; b(5)
ERASE b
PRINT "b(5) after ERASE is non-existent."
PRINT "See? We now get a subscript out of range error at the next line..."
b(5) = 7 ' Errors out. This dynamic array in the main was de-initialized, as expected.

SUB pete
    REDIM a(10) ' Dynamic array in a sub.
    a(5) = 3
    PRINT "a(5) in Pete sub:"; a(5)
    ERASE a
    PRINT "a(5) after ERASE is non-existent."
END SUB

Also, as a slightly related side note, CLEAR removes the initialization of dynamic arrays, but not a static ones, but CLEAR cannot be used in a sub.

Pete
If eggs are brain food, Biden takes his scrambled.
Reply
#5
Quote:Dammit! I was just about to use that as my signature. Now I have to come up with something else. Too bad Steve is busy! [Image: biggrin.png]

"So old I knew better once but forgot."

BTW Minerva was hinting at a memory leak if start Dynamic arrays in subs... does the above test for that?
Not seeing it:
Code: (Select All)
Do
    pete
Loop

Sub pete
    ReDim a$(10) ' Dynamic array in a sub.
    a$(5) = "3"
    Print "a$(5) in Pete sub:"; a$(5)
    'Erase a$
    'Print "erased a$() ? a$(5) "; a$(5)  'error subscript out of range
    Print "a$(5) after ERASE is non-existent."
    Print
End Sub

Pete just got a little bit older Smile
b = b + ...
Reply
#6
(12-07-2022, 08:18 PM)bplus Wrote:
Quote:Dammit! I was just about to use that as my signature. Now I have to come up with something else. Too bad Steve is busy! [Image: biggrin.png]

"So old I knew better once but forgot."

@bplus

"I'm old enough to know better, but still too young to care."

If it were up to Steve, I'm pretty sure he would just flame my av-ee-tar and say, "Pete should go back to school, on a short horse."

Pete
Reply
#7
(12-07-2022, 08:18 PM)bplus Wrote:
Quote:Dammit! I was just about to use that as my signature. Now I have to come up with something else. Too bad Steve is busy! [Image: biggrin.png]

"So old I knew better once but forgot."

BTW Minerva was hinting at a memory leak if start Dynamic arrays in subs... does the above test for that?


This is one of those things that is easy to test for and disprove.
Code: (Select All)
_Title "MemCheck"
Print "Open your Windows Task Manager and find the memory usage for this program."
Print "This is the amount of memory you're using prior to a call to foo."
Print
Print "Press ANY KEY..."
Sleep
foo
Print
Print "And this is how much memory you're using after exiting foo."
Print "Press ANY KEY..."
Sleep


Sub foo
    Dim array(1 To 1000) As String * 1000000 '1 million bytes per string element, with 1000 elements = approximately 1GB of memory
    For i = 1 To 1000
        array(i) = String$(1000, "*")
    Next
    Print
    Print "This is how much memory you're using within foo!"
    Print "Press ANY KEY..."
    Sleep
End Sub

Run it, open Task Manager...  Your program will use about 50MB of memory.   Hit any key, you go into SUB foo, and now are using over 1GB of memory.  Hit any key, exit foo, and that memory is now freed.  You're now back down to using the same 50MB of memory as previously.

No memory leak here.
Reply
#8
(12-07-2022, 10:13 PM)SMcNeill Wrote: Run it, open Task Manager...  Your program will use about 50MB of memory.   Hit any key, you go into SUB foo, and now are using over 1GB of memory.  Hit any key, exit foo, and that memory is now freed.  You're now back down to using the same 50MB of memory as previously.

No memory leak here.
So it means "CLEAR" is worthless in QB64 for its third parameter?

Maybe a redundant question since we're not in 16-bit any longer but declaring a static array that huge would have meant outright refusal to compile in the past. That's why I was being naive and said the thing about "memory leak".
Reply
#9
Yes, CLEAR stack and memory parameters are ignored in QB64. You can include them, but they do nothing.

Pete
If eggs are brain food, Biden takes his scrambled.
Reply
#10
Hi , I 'm  new here . But have persisting problem  ..I want to dim an array, or redim it in a sub and pass values through sub's parameter list . I get the dim  bounds reading a file ( in the sub) It wont compile. When I print the ubound before redim , I get 10, default size in BASIC it seems. Breaking the sub, declaring  arrays in the main is so awkward. Loads of thanks for a tip or clue ?
Reply




Users browsing this thread: 2 Guest(s)