[futurebasic] Re: [FB] Blockmove

Message: < previous - next > : Reply : Subscribe : Cleanse
Home   : May 2004 : Group Archive : Group : All Groups

From: Robert Purves <robert.purves@...>
Date: Mon, 31 May 2004 14:04:52 +1200
Rich Love wrote:

> The purpose for doing this is to shift a character array used as a 
> scroll buffer.
> XREF@ Array% (960, 207).....  960 is the number of rows in the buffer 
> and 207 is the number of columns.
> I want to shift the rows back one row.

>> I am block moving an array. It does work but I want to know if it is 
>> memory safe.
>> I am moving a block of memory from location 2 in the array to 
>> location 1.
>> What worries me is that I am moving the max number of bytes (397490) 
>> that the array is XREF'd.
>>
>> Is FB kind enough to let me do this or should I worry that I am 
>> corrupting some memory that is out of the bounds of my array?
>>
>> Here is the sample:
>>
>> XREF@ Array% (960, 207)
>> Array& = FN NEWHANDLE(397490)
>>
>> BLOCKMOVE @ Array%(2,0),@ Array%(1,0), 397490

Experience teaches us that programmers commonly make mistakes when 
calculating sizes of arrays and components of multidimensional arrays. 
'Magic numbers' (397490) in code all too often flag a bug.

It's best therefore to spell everything out and let the compiler do the 
calculations via some constants.  The method suggested below not only 
works correctly now, but lets you change the array bounds or type by 
editing a single place; it will be easily maintained in the future.  
Note that there is no execution overhead from calculating _myArraySize 
--- it's done at compile time.

'------
_maxRows = 960 // whatever
_maxCols = 207 // whatever
#define MyArrayType as short // byte, short, long...

_myRowSize   = (_maxCols + 1)*sizeof( MyArrayType )
_myArraySize = (_maxRows + 1)*_myRowSize
xref@ gArray(_maxRows, _maxCols) as MyArrayType
gArray = fn NewHandle( _myArraySize )
// or
//xref gArray(_maxRows, _maxCols) as MyArrayType
//gArray = fn NewPtr( _myArraySize )


// scroll, by moving rows 2:_maxRows to row 1
BlockMove @gArray(2, 0), @gArray(1, 0), _myArraySize - 2*_myRowSize

stop "Array size =" + str$( _myArraySize )
'------

Lastly, note the value of _myArraySize shown on running the demo. The 
magic number 397490 in the original code is indeed a bug.

Robert P.