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.