PrevNextUpHome SophiaFramework UNIVERSE 5.3

13.2. Array

SFXArray is data structure for operating a multiple of the elements as an array. In this class, any element can be directly accessed using the index.

[Note] SFXArray and SFXList

In the SFXArray class, an element can be directly accessed using the index. On the other hand, in the SFXArray class, accessing an element needs to be traversed via a two-way linked list. Therefore, accessing an element is faster than in the SFXList class.

In the SFXList class, inserting or deleting an element is only to maintain the pointers of the element in question and the neighboring elements. On the other hand, in the SFXArray class, it is necessay to to move elements after the element in question in the internal buffer memory. Therefore, inserting or deleting an element is slower than in the SFXList class.

In the default settings, when the first element is inserted, the internal buffer will be allocated by the size set with the SFXArray::SetThreshold function(default: size for 4 elements). Then, in case memory becomes insufficient while elements are inserted one by one, the internal buffer will be expanded by the cluster size set with the SFXArray::SetCluster function(default: size for 8 elements). Here, the size of one element is 4 byte.

When the internal buffer is expanded, new consecutive memory area bigger than the current one by the cluster size will be allocated and all data of existing elements will be copied there. Therefore, if expansion is performed frequently, it may become the cause of performance deterioration

If the number of the elements are known in advance, it is recommended to set the internal buffer size with the SFXArray::SetThreshold / SFXArray::SetCluster functions or to set the number of the elements with the SFXArray::SetSize function(*).

[Note] Note
If the internal buffer is expanded with the SFXArray::SetSize function, each element in the expanded area will be set to 0.

The code below is to define the array with data of the SInt32 type as elements.

// define the array with data of the SInt32 type as elements
SFXArray<SInt32> array;

// current status: array = () 
[Note] Note

The element size must be less than or equal 4 bytes.

The code below is to append 4 elements into the array with the SFXArray::InsertLast function.

// current status: array = () 

array.InsertLast(3);    // internal buffer for 4 elements will be allocated
// current status: array = (3) 

array.InsertLast(-15);  
// current status: array = (3, -15) 

array.InsertLast(0);    
// current status: array = (3, -15, 0) 

array.InsertLast(1003); 
// current status: array = (3, -15, 0, 1003) 
[Note] Note

When the SFXArray::InsertLast function is called first, internal buffer will be allocated by the size set with the SFXArray::SetThreshold function(by default, space for 4 elements).

The code to get and set the element of the array using the index is as follows:

// current status: array = (3, -15, 0, 1003) 

SInt32 n = array[1]; // n = -15
// current status: array = (3, -15, 0, 1003) 

array[2] = 6;
// current status: array = (3, -15, 6, 1003) 
[Note] Note

In case of list, no element can be get or set using the index.

The top or last element can be obtained with the SFXArray::GetFirst / SFXArray::GetLast function.

// current status: array = (3, -15, 6, 1003) 

// get the first element
SInt32 first = array.GetFirst(); // first = 3

// get the last element
SInt32 last  = array.GetLast();  // last  = 1003

To get the size (number of the elements) of the array, call the SFXArray::GetSize function.

// get the size (number of the elements) of the array
SInt32 n = array.GetSize(); // n = 4 

To insert an element into the array, call the SFXArray::Insert function.

// insert 99 after the second element
// since this is the 5th element, internal buffer expanded by the cluster size(by default, space for 8 elements) will be allocated newly
array.Insert(2, 99);     // array = (3, -15, 99, 6, 1003)
// current status: array = (3, -15, 99, 6, 1003) 

// insert -100 at the first position
array.InsertFirst(-100); // array = (-100, 3, -15, 99, 6, 1003) 
// current status: array = (-100, 3, -15, 99, 6, 1003) 
[Caution] Caution

When an element is inserted into an array, you have to note performance deterioration for the reasons below.

  • All elements after the element in question are moved.
  • If the internal buffer is full, memory reallocation will occur.

* In case of list, since heap memoy is allocated for each element and only maintaining the pointers on the neighboring elements is necessay, interting an element is fast.

To remove the elements of the array, call the SFXArray::Remove function.

// current status: array = (-100, 3, -15, 99, 6, 1003) 

// delete elements from array[3] to array[4]
array.Remove(3, 5); // array = (-100, 3, -15, 1003) 

// current status: array = (-100, 3, -15, 1003) 
[Note] Note

If the element is of the pointer type, the heap memory area which the pointer points to will not be released after the element is removed. Note that memory leakage may occur because of this.

To remove all elements of the array, call the SFXArray::Clear function. This function releases the internal buffer.

// current status: array = (-100, 3, -15, 1003) 

// remove all elements of array
array.Clear(); 

// current status: array = ()
// internal buffer will be released

To set the size of the array, call the SFXArray::SetSize function. If a bigger value than the current size of the array is specified in the argument, the array will be expanded and added elements will be set to 0. The values of the existing elements are same as before. If a samller value is specified, the array will be shrinked and elements whose index are bigger than or equals it will be removed.

[Tip] Tip

To update the element with the specified index, use the SFXArray::operator[] operator or the SFXArray::Set function.

// current status: array = ()

// set the size of array to 5: each appended element will be initialized with 0
array.SetSize(5); 

// current status: array = (0, 0, 0, 0, 0)

// update each element of array
SInt32 i;
for (i = 0; i < array.GetSize(); ++i) {
    array[i] = 10 * (i - 2) * (i - 2);
}

// current status: array = (40, 10, 0, 10, 40)

// set the size of array to 10
array.SetSize(10); 

// current status: array = (40, 10, 0, 10, 40, 0, 0, 0, 0, 0)
// only added elements will become 0, existing elements are same as before
[Note] Note

In case the number of the elements is known in advance, performance deterioration by memory reallocation can be evaded by setting to the appropriate size with the SFXArray::SetSize function. And, setting an element using the index is more effective than SFXArray::Insert / SFXArray::InsertFirst / SFXArray::InsertLast.

The code below is to search the element specified in the argument or check whether or not it exists. The SFXArray::FirstIndexOf / SFXArray::LastIndexOf function searches the element and gets the index. The SFXArray::Contains function checks whether or not the array includes the element.

// current status: array = (40, 10, 0, 10, 40, 0, 0, 0, 0, 0)

SInt32 x;
Bool   b;

// search the first element with the value of 10 and get its index
x = array.FirstIndexOf(10);     // x = 1

// search the first element with the value of 5 and get its index
x = array.FirstIndexOf(5);      // x = -1: since the element in question does not exist

// search the last element with the value of 10 and get its index
x = array.LastIndexOf(10);      // x = 3

// check whether or not the element with the value of 0 exists
b = array.Contains(0);          // b = true

// check whether or not the element with the value of 100 exists
b = array.Contains(100);        // b = false

To traverse the elements of the array, use the index, the iterator, or the enumerator. In case of the iterator, an element can be inserted or deleted.

[Note] Note

In case of list, no element can be accessed using the index.

Example 13.1. Traversing elements using the index

SInt32 i;

for (i = 0; i < array.GetSize(); ++i) {

    SInt32 n = array[i]; // the content of the element is stored into n

    // processing with n

}
[Note] Note
array[i] will be inline-expanded and become the i-th element of the internal buffer.

The above code is similar to the following. The avove is more superior than the below in performance.

Example 13.2. Traversing elements using the enumerator

SFXArray<SInt32>::Enumerator etor = array.GetFirstEnumerator();

while(etor.HasNext()) {

    SInt32 n = etor.GetNext(); // the content of the element is stored into n

    // processing with n

}

Example 13.3. Traversing elements using the iterator

SFXArray<SInt32>::Iterator itor = array.GetFirstIterator();

while(itor.HasNext()) {

    SInt32 n = itor.GetNext(); // the content of the element is stored into n

    // processing with n

}
[Note] Note
Since "etor.GetNext()" or "itor.GetNext()" is function call, accessing an element directly using the index is more cost-effective than using the enumerator or the iterator.