Main Menu

Arrays and their elements

Started by thaaks, April 21, 2006, 01:35:42 PM

Previous topic - Next topic

thaaks

Hi,
while testing the dynamic array code for my Space Invaders Tutorial I detected the following:

If you DIM an array with say 10 you really get 11 elements, namely those with index 0 to 10 (which makes 11: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

Accessing the array with these 11 indices works fine, all other cause a runtime error (as expected).

But: GetArrayElements() returns 10 elements for this array, although there are 11.

And: ClearArrayCells() allows clearing of all 11 elements.
Also: ClearArray() clears all 11 elements.

And: I used a typed DIM Array. Calling ClearArrayCells() and ClearArray() does not only clear the first field of each type but clears the whole type element. That's missing or unclear in the online help. And as my testcase below demonstrates it doesn't care about strings or ints - everything becomes zero.

Needs a bit of cleanup, hm?
But I love the functionality in general  :D

Tommy
PlayBASIC Code: [Select]
; PROJECT : DynArrayTest
; AUTHOR : Tommy Haaks
; CREATED : 21.04.2006
; EDITED : 21.04.2006
; ---------------------------------------------------------------------

Constant DYNARRAY_GROWTH = 7

Type TArrayElem
inUse; this must be the first field and is an int and either 0 (false) or 1 (true)
EndType

Function GetFree(list().TArrayElem)
Local items, freeItem
Repeat
items=GetArrayElements(list().TArrayElem, 1)
freeItem=FindArrayCell(list().TArrayElem, 0, 1, items + 1, 0)
If freeItem = -1 Then ReDim list(items + DYNARRAY_GROWTH) As TArrayElem
Until freeItem <> -1
EndFunction freeItem


Function Add(list().TArrayElem)
Local index, sprite
index = GetFree(list().TArrayElem)
list(index).inUse = True
EndFunction index


Function Delete(list().TArrayElem, index)
If index > -1
If index <= GetArrayElements(list().TArrayElem, 1)
ClearArrayCells list().TArrayElem, index, 1, 1, 0
EndIf
EndIf
EndFunction


Function DeleteAll(list().TArrayElem)
ClearArray list().TArrayElem, 0
RemStart
Local items, e
items = GetArrayElements(list().TArrayElem, 1)
ClearArrayCells list().TArrayElem, 0, 1, items, 0
RemEnd

EndFunction

; MY TEST CODE STARTS HERE

Type TTest As TArrayElem
index
testValue
testStr$
EndType

Dim TestArray(0) As TTest
Cls 0
FlushKeys

Print "Allocating 11 elements with index 0 to 10"
For i = 0 To 10
freeSlot = Add(TestArray().TTest)
TestArray(freeSlot).index = i
TestArray(freeSlot).testValue = 42
TestArray(freeSlot).testStr$ = "Tommy"
Next
elements = GetArrayElements(TestArray().TTest, 1)
Print "TestArray has " + Str$(elements) + " elements"
For i = 0 To elements
Print "TestArray(" + Str$(i) + ").inUse = " + Str$(TestArray(i).inUse) + ", index = " + Str$(TestArray(i).index) + ", testValue = " + Str$(TestArray(i).testValue) + ", testStr$ = " + TestArray(i).testStr$
Next
Print ""
Print "Press any key to test deleting some elements"
Sync
WaitKey

Cls 0
FlushKeys
Print "Deleting elements 0, 5 and 7"
Delete(TestArray().TTest, 0)
Delete(TestArray().TTest, 5)
Delete(TestArray().TTest, 7)

elements = GetArrayElements(TestArray().TTest, 1)
Print "TestArray has " + Str$(elements) + " elements"
For i = 0 To elements
Print "TestArray(" + Str$(i) + ").inUse = " + Str$(TestArray(i).inUse) + ", index = " + Str$(TestArray(i).index) + ", testValue = " + Str$(TestArray(i).testValue) + ", testStr$ = " + TestArray(i).testStr$
Next
Print ""
Print "Press any key to test deleting all elements"

Sync
WaitKey

Cls 0
FlushKeys
Print "Deleting all elements"
DeleteAll(TestArray().TTest)

elements = GetArrayElements(TestArray().TTest, 1)
Print "TestArray has " + Str$(elements) + " elements"
For i = 0 To elements
Print "TestArray(" + Str$(i) + ").inUse = " + Str$(TestArray(i).inUse) + ", index = " + Str$(TestArray(i).index) + ", testValue = " + Str$(TestArray(i).testValue) + ", testStr$ = " + TestArray(i).testStr$
Next

Sync
WaitKey





kevin

Arrays in Basic are zero inclusive.    So dimensioning an array with Zero elements is perfectly legal.    To be honest it's not something that i'm terribly fond of today, but it's normal behavior.    It's also the reason why there's a few extra commands for checking the status of arrays and deleting them (undim).

  GetArrayElements (man that needs a short cut)  despite what the name suggests, returns the  highest legal index in the queried array.  Eg..  In a DIM Table(10), that would be 10.   So you can iterate through the legal range of elements.  It's expected the user knows that range is from 0 to highestindex.

  Re: Typed arrays.  And clearing/searching etc elements.  

  A typed array is basically a list of pointers to the allocated type structures.  When you use the array commands on a typed array, your manipulating the pointers and not the field data as your assuming.   So clearing a cell, is nulling a pointer to previously allocated type.  Hence deleting it.  

  Currently there's no way (that I can think of atm) to manipulate the Type dynamically.

thaaks

QuoteArrays in Basic are zero inclusive.    So dimensioning an array with Zero elements is perfectly legal.    To be honest it's not something that i'm terribly fond of today, but it's normal behavior.    It's also the reason why there's a few extra commands for checking the status of arrays and deleting them (undim).
Okay. Learned something new here. But does that mean that Dim Foo(0) allocates a one element array? Sometimes Basic is so unlogical  :P
QuoteGetArrayElements (man that needs a short cut)  despite what the name suggests, returns the  highest legal index in the queried array.  Eg..  In a DIM Table(10), that would be 10.   So you can iterate through the legal range of elements.
Then I would suggest renaming the command (GetHighestIndex).
QuoteIt's expected the user knows that range is from 0 to highestindex.
Is that mentioned somewhere in the online documentation? I know that you do it in your sample code (storing special information in entry 0 for example).
QuoteRe: Typed arrays.  And clearing/searching etc elements. 

   A typed array is basically a list of pointers to the allocated type structures.  When you use the array commands on a typed array, your manipulating the pointers and not the field data as your assuming.   So clearing a cell, is nulling a pointer to previously allocated type.  Hence deleting it.  
What happens to the allocated type after nulling the pointer? Is it garbage collected? Or do I have a memory leak? I assume one has to delete ressources stored in that type (like sound files, images, sprites) manually before clearing the cell and nulling the pointer?

Cheers,
Tommy

kevin

QuoteOkay. Learned something new here. But does that mean that Dim Foo(0) allocates a one element array?

 Yep, 1 element,  index 0
 
QuoteIs that mentioned somewhere in the online documentation? I know that you do it in your sample code (storing special information in entry 0 for example).

  Yep. Under DIM



FACTS:

* Array Indexes are zero inclusive. That means 0,1,2, etc .. up to the Number of Elements are valid Indexes.



QuoteWhat happens to the allocated type after nulling the pointer? Is it garbage collected? Or do I have a memory leak?


  We have major paradox...Run for it marty !  :)

  Well, maybe not.. If any pointers are overwritten the data is freed for you.


QuoteI assume one has to delete ressources stored in that type (like sound files, images, sprites) manually before clearing the cell and nulling the pointer?

   The user has delete any loosely associated media.   Since there's no 'Sprite/Image' etc data type, I can't reliably determine the meaning of a particluar field.    If there was, they could released with the type.