Hello, I'm trying to find some help with code that I've been maintaining and currently trying to modify.
Basically, I am working with a single array of length "m", call it the "max" array. Other than knowing that each entry in the "max" array is nonnegative, I have no other information on this array until runtime (including the length "m"). I want to create a linked list of structs, with each struct containing two integer values, lbval and ubval.
struct item {
int lbval;
int ubval;
};
Each list item is a struct, corresponds to each array beneath (more precisely, lexicographically smaller than) the "max" array (up until the origin of 0 in all entries). So, for example, if m = 3, and the max array is [9 9 9], then I need (9+1)*(9+1)*(9+1) = 1000 structs in my linked list.
So, my first function CreateList attempts to create this linked list. It takes in the address of an item** (originally set to NULL). It then calls itself recursively until recurseLevel is one less than "m" (the length of the array). It then allocates space for items on the list. In a nutshell, the function starts with [0 ... ], goes to [0 0 ... ], etc., and eventually drills down to [0 0 0 x], where it initializes all arrays [0 0 0 0], [0 0 0 1], [0 0 0 2], etc. It then proceeds to [0 1 ... ], and so on...
void CreateList(int arrayLength, int recurseLevel, int* maxArray, item ***current)
{
int i;
int size = (int) maxArray[recurseLevel] + 1;
if (recurseLevel == arrayLength - 1)
{
*current = (item **) malloc (size * sizeof(item *));
for (i = 0; i < size; i++)
{
(*current)[i] = (item* ) malloc (sizeof(item));
(*current)[i]->lbval = 0;
(*current)[i]->ubval = 1000;
}
}
else
{
*current = (item **) malloc(size * sizeof(item *));
for (i = 0; i < size; i++)
{
CreateRhs(arrayLength, recurseLevel + 1, maxArray, (item ***) (*current + i));
}
}
}
The function FindItem is used to access items on the list, returning a pointer to that item.
item* FindItem(int arrayLength, int *target, item **itemList)
{
int i;
item **current;
item *tempPtr;
current = itemList;
for (int i = 0; i < arrayLength - 1; i++)
{
current = (item**) current[target[i]];
}
*tempPtr = (item*) current[target[i]];
return(*tempPtr);
}
So, this approach allocates a LOT of memory if the size "m", as well as the entry values, are large, and this allocation is accomplished during the list's initialization. So instead of allocating all of the memory up front for every array in CreateList, I would like to just create the skeleton of the list -- meaning that in the last step of each recursion, I want to do:
(*current)[i] = NULL;
instead of allocating and setting the lbval and ubval values there. Then, when FindItem is called later in my code to look up an item, I would like to add a test to see if "tempPtr == NULL", and if so, to initialize that item there, something like:
if (tempPtr == NULL)
{
tempPtr = (item* ) malloc (sizeof(item));
tempPtr->lbval = 0;
tempPtr->ubval = 1000;
}
My question is, would the above changes work - or am I off somewhere? I've tried to implement this idea, and though the logic seems correct to me, It's not running correctly (in particular, though a particular item will be initialized in FindItem, later it will again point to NULL (so it seems that the initialization was only done locally?).
Just not sure why it's happening - maybe someone more experienced can lend a hand here! Also, if there is a better way to do what I'm doing, or I can explain anything furher, please let me know.
Thanks for reading, and for your help!