Dynamic Arrays


Overview

A dynamic array has a type, which is the type of its elements. The type of the dynamic array is declared when a new array instance is created via u_array_create and must be one of the types in u_array_type_t. Available types are the standard C types supported by the target platform, plus a generic pointer type for user defined types. A couple of getter/setter methods is provided for each u_array_type_t entry, e.g. see u_array_get_char and u_array_set_char.

The following is some toy code showing basic operations (create, set, get, destroy) using double precision complex numbers (C99):

    u_array_t *a = NULL;
    size_t idx;
    long double _Complex c0, c1;

    // create an array to store double precision complex numbers
    // array resize is handled transparently
    con_err_if (u_array_create(U_ARRAY_TYPE_LONG_DOUBLE_COMPLEX, 0, &a));

    // insert values from 0+0i to 10+10i at increasing indexes,
    // also check that what has been inserted matches what we get back
    for (idx = 0; idx < 10; idx++)
    {
        c0 = idx + idx * _Complex_I; 
        con_err_if (u_array_set_long_double_complex(a, idx, c0, NULL));
        con_err_if (u_array_get_long_double_complex(a, idx, &c1));
        con_err_if (creal(c0) != creal(c1) || cimag(c0) != cimag(c1));
    }

    // now overwrite previously set values with new ones
    for (idx = 0; idx < 10; idx++)
    {
        long double _Complex c2;

        c0 = (idx + 10) + (idx + 10) * _Complex_I;
        con_err_if (u_array_set_long_double_complex(a, idx, c0, &c2));
        u_con("overwrite %lf + %lfi at %zu with %lf + %lfi", 
                creal(c2), cimag(c2), idx, creal(c0), cimag(c0)); 
        con_err_if (u_array_get_long_double_complex(a, idx, &c1));
        con_err_if (creal(c0) != creal(c1) || cimag(c0) != cimag(c1));
    }

    // ok, enough stress, dispose it :)
    u_array_free(a);
Note:
The getter/setter interfaces for generic pointers are different from all the other, see u_array_get_ptr and u_array_set_ptr for details.

Defines

#define U_ARRAY_NSLOTS_DFL   512
 default number of slots on array creation (can be changed at compile time via -DU_ARRAY_NSLOTS_DFL=nnn flag)
#define U_ARRAY_RESIZE_PAD   100
 right-pad when doing dynamic resize (can be changed at compile time via -DU_ARRAY_RESIZE_PAD=nnn flag)

Typedefs

typedef struct u_array_s u_array_t
 Dynamic array base type.

Enumerations

enum  u_array_type_t {
  U_ARRAY_TYPE_UNSET = 0, U_ARRAY_TYPE_CHAR, U_ARRAY_TYPE_U_CHAR, U_ARRAY_TYPE_SHORT,
  U_ARRAY_TYPE_U_SHORT, U_ARRAY_TYPE_INT, U_ARRAY_TYPE_U_INT, U_ARRAY_TYPE_LONG,
  U_ARRAY_TYPE_U_LONG, U_ARRAY_TYPE_FLOAT, U_ARRAY_TYPE_DOUBLE, U_ARRAY_TYPE_PTR
}
 

Available dynamic array types, i.e. the standard C types supported by the target platform, plus an any type pointer for user defined types.

More...

Functions

int u_array_create (u_array_type_t t, size_t nslots, u_array_t **pda)
 Create a new array object.
void u_array_free (u_array_t *da)
 Free the array object: the array does not own the pointers in it, the client must free them explicitly.
int u_array_resize (u_array_t *da, size_t idx)
 Grow the array so that the supplied index can be accomodated.
int u_array_set_char (u_array_t *da, size_t idx, char v, char *pold)
 Put value v into the array da at index idx.
int u_array_set_u_char (u_array_t *da, size_t idx, unsigned char v, unsigned char *pold)
 Setter for the unsigned char type.
int u_array_set_short (u_array_t *da, size_t idx, short v, short *pold)
 Setter for the short type.
int u_array_set_u_short (u_array_t *da, size_t idx, unsigned short v, unsigned short *pold)
 Setter for the unsigned short type.
int u_array_set_int (u_array_t *da, size_t idx, int v, int *pold)
 Setter for the int type.
int u_array_set_u_int (u_array_t *da, size_t idx, unsigned int v, unsigned int *pold)
 Setter for the unsigned int type.
int u_array_set_long (u_array_t *da, size_t idx, long v, long *pold)
 Setter for the long type.
int u_array_set_u_long (u_array_t *da, size_t idx, unsigned long v, unsigned long *pold)
 Setter for the unsigned long type.
int u_array_set_float (u_array_t *da, size_t idx, float v, float *pold)
 Setter for the float type.
int u_array_set_double (u_array_t *da, size_t idx, double v, double *pold)
 Setter for the double type.
int u_array_get_char (u_array_t *da, size_t idx, char *pv)
 Get the element of char array da at index idx and save it at *pv.
int u_array_get_u_char (u_array_t *da, size_t idx, unsigned char *pv)
 Getter for the unsigned char type.
int u_array_get_short (u_array_t *da, size_t idx, short *pv)
 Getter for the short type.
int u_array_get_u_short (u_array_t *da, size_t idx, unsigned short *pv)
 Getter for the unsigned short type.
int u_array_get_int (u_array_t *da, size_t idx, int *pv)
 Getter for the int type.
int u_array_get_u_int (u_array_t *da, size_t idx, unsigned int *pv)
 Getter for the unsigned int type.
int u_array_get_long (u_array_t *da, size_t idx, long *pv)
 Getter for the long type.
int u_array_get_u_long (u_array_t *da, size_t idx, unsigned long *pv)
 Getter for the unsigned long type.
int u_array_get_float (u_array_t *da, size_t idx, float *pv)
 Getter for the float type.
int u_array_get_double (u_array_t *da, size_t idx, double *pv)
 Getter for the double type.
void * u_array_set_ptr (u_array_t *da, size_t idx, void *v, int *prc)
 Dynamic array setter interface for generic pointer values.
void * u_array_get_ptr (u_array_t *da, size_t idx, int *prc)
 Dynamic array getter interface for generic pointer values.

Enumeration Type Documentation

Enumerator:
U_ARRAY_TYPE_UNSET 

no type

U_ARRAY_TYPE_CHAR 

char

U_ARRAY_TYPE_U_CHAR 

unsigned char

U_ARRAY_TYPE_SHORT 

short int

U_ARRAY_TYPE_U_SHORT 

unsigned short int

U_ARRAY_TYPE_INT 

int

U_ARRAY_TYPE_U_INT 

unsigned int

U_ARRAY_TYPE_LONG 

long int

U_ARRAY_TYPE_U_LONG 

unsigned long int

U_ARRAY_TYPE_FLOAT 

float

U_ARRAY_TYPE_DOUBLE 

double

U_ARRAY_TYPE_PTR 

generic pointer

Definition at line 42 of file array.h.


Function Documentation

int u_array_create ( u_array_type_t  t,
size_t  nslots,
u_array_t **  pda 
)
Parameters:
t the type of the elements in this array, i.e. one of the standard C types (which have 1:1 mapping with U_ARRAY_TYPE_*'s) or a pointer type (select U_ARRAY_TYPE_PTR in this case)
nslots the initial number of slots to be created (set it to 0 if you want the default)
pda the newly created array object as a result argument
Return values:
0 on success
-1 on error

Definition at line 135 of file srcs/toolbox/array.c.

References u_array_free(), U_ARRAY_NSLOTS_DFL, and u_zalloc().

void u_array_free ( u_array_t da  ) 
Parameters:
da the array object that has to be disposed
Returns:
nothing

Definition at line 174 of file srcs/toolbox/array.c.

References u_free().

Referenced by u_array_create().

int u_array_get_char ( u_array_t da,
size_t  idx,
char *  pv 
)
Note:
An identical interface -- aside from the type of pv parameter -- is given for any supported type.
Parameters:
da An already instantiated dynamic array
idx The index at which the element shall be retrieved
pv The address at which the retrieved value is copied
Return values:
0 on success
-1 on error
void* u_array_get_ptr ( u_array_t da,
size_t  idx,
int *  prc 
)

Try to retrieve the pointer at position idx from the dyamic array da. If supplied (i.e. non-NULL) the result argument *prc will hold the return code of the whole get operation. We could not preserve the same interface as all the other standard types because the void** out parameter would be easily abused through an incorrect cast. The following sample should illustrate how to correctly use the interface:

      int rc = 0;
      size_t i = 231; // some random index
      my_t *v = NULL; // the value that we are going to retrieve

      // get the new value from the array at some conveninent index, 
      v = u_array_get_ptr(da, i, &rc);
      dbg_err_if (rc == -1);

      // do something with 'v'
      ...
Parameters:
da An already instantiated dynamic array
idx The index at which the element v shall be stored
prc If non-NULL this result argument will store the return code of the whole operation, i.e. 0 if successfull, -1 if something went wrong
Returns:
the value stored at index idx (note that it can be NULL and therefore it can't be used to distinguish a failed operation.

Definition at line 416 of file srcs/toolbox/array.c.

int u_array_resize ( u_array_t da,
size_t  idx 
)
Parameters:
da the array object
idx the index that needs to be accomodated/reached
Return values:
0 on success
-1 on error

Definition at line 193 of file srcs/toolbox/array.c.

References U_ARRAY_RESIZE_PAD, and u_realloc().

int u_array_set_char ( u_array_t da,
size_t  idx,
char  v,
char *  pold 
)

Put value v into the array da at index idx. In case pold is not NULL, the overridden value (if any) is copied out.

Note:
An identical interface -- aside from the type of v and pold parameters -- is given for any supported type.
Parameters:
da An already instantiated dynamic array
idx The index at which the element v shall be placed Transparent resize is handled in case the index were out of actual array bounds
v The value that must be copied into the array
pold If not NULL, it is the address at which the overridden element (if any) shall be copied
Return values:
0 on success
-1 on error
void* u_array_set_ptr ( u_array_t da,
size_t  idx,
void *  v,
int *  prc 
)

Try to put some generic pointer v at position idx into the dyamic array da. If supplied (i.e. non-NULL) the result argument *prc will hold the return code of the whole set operation. We could not preserve the same interface as all the other standard types because the void** out parameter would be easily abused through an incorrect cast. The following sample should illustrate how to correctly use the interface:

      int rc = 0;
      size_t i = 231; // some random index
      my_t *old_v, *v = NULL; // the value that we are going to store

      // make room for your new object and fill it some way
      dbg_err_sif ((v = u_zalloc(sizeof(my_t))) == NULL);
      v->somefield = somevalue;
      
      // set the new value in the array at some conveninent index, 
      // and dispose the old one in case it was set
      old_v = u_array_set_ptr(da, i, v, &rc);
      dbg_err_if (rc == -1);
      if (old_v)
          my_free(old_v);
      ...
Parameters:
da An already instantiated dynamic array
idx The index at which the element v shall be stored
v The value that must be stored
prc If non-NULL this result argument will store the return code of the whole operation, i.e. 0 if successfull, -1 if something went wrong
Returns:
the old value stored at index idx (can be NULL)

Definition at line 355 of file srcs/toolbox/array.c.


←Products
© 2005-2012 - KoanLogic S.r.l. - All rights reserved