tags:

views:

85

answers:

1

Suppose I have the following:

typedef struct {
   int itemSize;
   int count;
   void *list;
} Mystruct;

Mystruct *InitStruct(int itemSize, int count) 
{
  Mystruct *my = malloc(sizeof(Mystruct));
  my->itemSize = itemSize;
  my->count = count;
  //What is the best way to initialize list?  For example:
  //my->list = malloc(count * sizeof(void *));   OR
  //my->list = malloc(count * sizeof(itemSize));
}

//The following should return a pointer to the element stored at a given index 
void *Retrieve(const MyStruct *my, int index)
{
   void *item;
   //What is the best way to return a pointer to the item at the given index from 
   //my->list?
}

Mystruct is similar to an array and void *list is supposed to store the elements or pointers to the elements. Mystruct *InitStruct is a function that initializes a Mystruct pointer and void *Retrieve is a function that returns a pointer to the element stored at a given index.

First, how should I initialize void* list? Should it hold the actual elements or be an array of pointers pointing to the elements?

Second, using the void *Retrieve function, how do I return a pointer to the element stored at a given index in my->list?

+1  A: 

On the first point, if all elements are the same size, as that itemSize name suggests, then adding one level of indirection (having list point to pointers to items, rather than to items directly) seems to have no added value, so I'd use my->list = malloc(count * itemSize);.

On the second point, (char*)my->list + itemSize*index should work. You may first want to check that index < my->count, of course (maybe you want to return NULL in that case rather than an invalid pointer).

Alex Martelli
Yes, I removed any error checking code to make the post as concise as possible. Why did you typecast my->list with (char *)? Shouldn't I use (void *)?
idealistikz
@idealistikz, it's not C-standard-compliant to do address arithmetic on `void*`, e.g. gcc with -pedantic and -Wall would give you a `pointer of type ‘void *’ used in arithmetic` warning -- the cast lets the code compile perfectly without warnings even at the highest severity levels, just as it should be.
Alex Martelli
sizeof(itemSize) is sizeof(int). I think itemSize should be used directly - malloc(count * itemSize)
Maciej Hehl
@Maciej, excellent point, editing accordingly.
Alex Martelli