Description
This method allocates an array by specifying the number of elements and the size of every element. You may call CTARR_Alloc many times on the same array with different item sizes and number of items. However, if the array already had elements, they will be lost because the CTARR_Alloc method replaces the existing items with new items.
Since the array may contain data of any type and of any size, initialization cannot be automated by the class. You can provide the initialization data that each item will assume when re-allocating the array.
Prototype
DCTARR_Alloc...
D PR 10I 0
D
D@This * Value
D@NumItems 10I 0 Value
D@ItemSize 10I 0 Value
D@InitData * Value
Parameters
@This
Type | Pointer (*) |
Passing Mode | By Value |
Description | The address of an array instance. This pointer MUST be obtained through a call to CTARR_Constructor. |
@NumItems
Type | 10I 0 |
Passing Mode | By Value |
Description | The number of items the array is to contain. |
@ItemSize
Type | 10I 0 |
Passing Mode | By Value |
Description | The size in bytes of every item within the array. |
@InitData
Type | Pointer (*) |
Passing Mode | By Value |
Description | The address of a data buffer that holds the data to be copied to each array item. Make sure the buffer is at least the same size as the @ItemSize parameter or else, garbage will be copied to every array item. |
Return Values
Symbolic Constant | Value | Description |
CS_SUCCESS | 0 | The array was allocated successfully. |
CS_FAILURE | 1 | The array could not be allocated. |
Notes
Allocation vs Construction
Allocation is distinct from construction in the sense that a CTARR instance is really a data structure which holds the actual array along with data to manage the array. Allocation is the process of specifying the size (number of elements) and the size of each item within a constructred array. It also allocates the buffer that will hold each item.
But for allocation to happen, an instance of type CTARR must already exist (that it a CTARR must already be constructed). Calling the CTARR_Alloc method several times on the same CTARR instance pointer does not create several distinct arrays. Rather, it replaces existing data with new data within the CTARR instance; this means that calling CTARR_Alloc destroys whatever data was already present and replaces it with initialized or uninitialized data, depending if the call provided initilization data.
If you want two distinct arrays, you must call the CTARR_Constructor method twice and keep each returned pointer in their own separate variable. You can then allocate their respective size with CTARR_Alloc.
Initializing an array during allocation
The fourth parameter to the CTARR_Alloc method points to a buffer that will be copied to every item in the newly allocated array. This is provided because the CTARR class does not keep type information on the items its objects hold. The initialization data is optional and you can specify *Null if you do not whish to set items to a particualr value; the data held in the items however will be undefined and may be incompatible with the actual data intended for the items (such as character data in numeric fields).
Zero size arrays and zero size items
It is possible to allocate an array with zero items. It is also possible to allocate an array with items of size zero. All methods will behave consistently under those conditions, regardless if a zero size array or an array with items of zero size makes sense (it might have unforseen applications so it is supported).
Examples
HDatEdit(*YMD)
*--------------------------------------------------------------
* Common Definitions
*--------------------------------------------------------------
/Include QINCSRC,CTBASE
DEntryProc Pr ExtProc('EXLST09')
DEntryProc PI
*-------------------------------------------------------------------------------
* Main
*-------------------------------------------------------------------------------
DArray S *
DCount S 10I 0
Dn S 10I 0
DRc S 10I 0
DSize S 10I 0
DBytes S 10I 0
DBuffer S 32A
DRecord DS Qualified
DF1 10I 0
DF2 25A
DF3 n
/Free
Array = CTARR_Constructor();
// Let's allocate an array of size 3
// And initialize each item with the string
// "HELLO"
Buffer = 'HELLO';
CTARR_Alloc(Array: 3: %Size(Buffer): %Addr(Buffer));
// Look at each item
For n=1 To CTARR_Count(Array) By 1;
Buffer = *Blanks;
CTARR_Get(Array: %Addr(Buffer): n);
EndFor;
// Let's allocate an array of size 3
// with items of size 0; we will even
// initialize the array ...
Buffer = 'HELLO';
CTARR_Alloc(Array: 3: 0: %Addr(Buffer));
// Look at each item
For n=1 To CTARR_Count(Array) By 1;
Buffer = *Blanks;
CTARR_Get(Array: %Addr(Buffer): n);
EndFor;
// Get item at index 1
// Our buffer value will remain intact
// since nothing was copied; but the
// method will return a failure code ...
Buffer = 'SOME VALUE';
Rc = CTARR_Get(Array: %Addr(Buffer): 1);
If Rc = CT_FAILURE;
Buffer = 'Nothing retrieved!';
EndIf;
// Let's allocate an array of size 0
// with items the size of our record.
Clear Record;
CTARR_Alloc(Array: 0: %Size(Record): %Addr(Record));
// Look at each item ... we won't because
// there are no items, we will not
// go in the loop
For n=1 To CTARR_Count(Array) By 1;
Buffer = *Blanks;
CTARR_Get(Array: %Addr(Record): n);
EndFor;
// Get item at index 1; this will return
// a failure code because the index is out
// of range
Rc = CTARR_Get(Array: %Addr(Record): 1);
// Let's allocate an array of size 2
// And initialize each item with
// a data record holding default values
// for differernt types of fields
Record.F1 = 0;
Record.F2 = *Blanks;
Record.F3 = *Off;
CTARR_Alloc(Array: 2: %Size(Record): %Addr(Record));
// Look at each item at how they have been initialized
// with proper default values
For n=1 To CTARR_Count(Array) By 1;
Clear Record;
CTARR_Get(Array: %Addr(Record): n);
EndFor;
// Let's allocate an array of size 4
// with items the size of our record
// but with no initialization data
CTARR_Alloc(Array: 4: %Size(Record): *Null);
// Look at each item to see how they have been initialized;
// You will see that inconsistent data is fetched ...
// the program may even crash.
For n=1 To CTARR_Count(Array) By 1;
CTARR_Get(Array: %Addr(Record): n);
EndFor;
CTARR_Destructor(Array);
*InLr = *On;
Return;
/End-Free