
Originally Posted by
Yonut
Just to add my two cents to the OP's problem...
I found that, whenever possible, I need to make my arrays +1. Then I can store the total items in the array in the first position. `array[0] = total`.
Now, if it is a numeric array, adding the total isn't a problem (usually). If it's a char array, you can use an `itoa` or `sprintf` function to add it to the first position. `sprintf(array[0], "%s", total)`
Then when you send the array to another function, the first thing you do is unpack the array:
Code:
int total = array[0];
char *new_array = &array[1];
or
Code:
int total = atoi(array[0]);
char *new_array = &array[1];
Although I don't know how others feel about this method, I find it very reasonable when dealing with multiple arrays/functions.
Well that's certainly one way to do it, I still prefer to just store the needed data in a common struct, here's one straight out of my code:
Code:
typedef struct _BUFFER BUFFER, BUF, BUFF, STRING, STR;
typedef uint* (*objpos_cb)( void *obj );
/* This is to be used on global buffers */
typedef struct _NODES
{
LOCK* _lock;
const ucap Vsize;
/* voidNode attempts to avoid new allocations by storing terminated nodes
* in erased, if it can't do that then it will actually de-allocate the
* memory, voidCB will be called at this point */
BUFFER *shared, *erased;
object_cb makeCB, termCB, voidCB;
objpos_cb gaveCB;
} NODES;
#define INIT_NODES( T ) \
{ \
NULL, sizeof(T), NULL, NULL, \
_MAKE_##T, _TERM_##T, _VOID_##T, _GAVE_##T \
}
...
struct _BUFFER
{
LOCK* _lock;
bool _uniq;
uint _node;
dint fault;
ucap Vsize, bytes;
uint total, count;
void* array;
};
extern NODES _buffers;
I have some management functions to go along with both of these, Vsize refers to the size of individual elements, _lock is for thread safety, when it's not NULL it means no actions should be taken by the thread attempting to take control of the object until the thread that has it empties the lock, _uniq indicates that every element should be unique and 0 is reserved for deliberate failure (so improperly passed or initialised indices will cause NULL or 0 to be returned when using them to access the array), _node is just for indicating where in the parent buffer it the object can be found.
As for nodes that's for garbage collection, they're global objects that note all the objects passed to it, it tries to preserve objects for re-assignment with the termCB function but will default to voidCB if it was unable to procure the memory for storing the index of the deleted object in the "erased" buffer, Vsize holds the same meaning but the "shared" buffer holds pointers which more often than not are a different size to what is stored so the Vsize parameter is used to allocate then 0 the memory for the object before passing onto makeCB to do it's thing, voidCB is called in the even of makeCB failing before de-allocating the memory and passing back to the caller, I use these functions because the actions are the same for any object I put in garbage collection and I don't want to repeat code that is better placed in a node management function.