Home > Mobile >  How to handle array of void pointers
How to handle array of void pointers

Time:12-11

I would like to get a reference to an element at position in an array of void pointers. This is my function, I don't know if am doing it correctly. I have these two functions:

typedef struct vector 
{
  void **array;
  size_t size;
}vector;

I believe this gets the reference to the element at position pos.

void **get_at(vector *this, size_t pos) 
{
   assert(pos >=0 && pos < this->size);

   return &this->array[pos];
}

I believe this gets the pointer to the element at position pos.

void *at(vector *this, size_t pos) 
{
   assert(pos >=0 && pos < this->size);

   return this->array[pos];
}

I just would like to know if am correct with this implementation.

Just one more question: If I want to destroy the array, is doing it this way enough? Do I have to loop through the array elements freeing the memory held by each element?

void destroy(vector *this)
{
  free(this->array);
  free(this);
}

CodePudding user response:

Do I have to loop through the array elements freeing the memory held by each element?

This is something only you can know.

There is a notion of ownership that is pervasive in all languages that support manual memory management. Every object is owned by some other object (or maybe by a group of objects but that's a bit more involved). When the owner dies, all objects owned by it die too.

We tend to personify the objects a bit, so you will often hear questions like "who owns this?". This "who" refers to an object, not to a person.

You have a vector of pointers that point to a bunch of objects. Who owns these objects? This is up to you to decide.

If the vector itself is the owner, then it will be a good idea to free the objects when the array itself is freed. Note that freeing an object may be a bit more involved than just calling free() (just imagine that each of these objects is another vector). This is why a good vector would look something like this:

typedef struct vector 
{
  void **array;
  size_t size;
  void (*destroy)(void*); // call this for each object
                          // when freeing the vector
} vector;

You assign the destroy member when you initialise your vector.

Your destroy function would look like this:

void destroy(vector *this)
{
  if (this->destroy) 
    for (int i = 0; i < this->size;   i) 
      this->destroy(this->array[i]);
  free(this->array);
  free(this);
}

If your vector doesn't own objects it points to, it shouldn't try to destroy them. This vector implementation works in this case too, just assign a null pointer to this->destroy.

You should design a coherent ownership structure for your program. There are no universal recipes.


get_at and at look OK as is.

  • Related