I'm writing some C code where I want to have a NULL-terminated GPtrArray containing static strings. Typically, I would use g_ptr_array_new_null_terminated () to construct a NULL-terminated GPtrArray, but it requires me to specify a function that frees the elements upon destruction—something you don't want with statically allocated strings, of course. However, I don't find any constructor that gives you a NULL-terminated array that doesn't require providing an element free function: both g_ptr_array_new_from_null_terminated_array () and g_ptr_array_new_take_null_terminated () require an element_free_func argument that cannot be set to NULL according to the documentation.
One option would of course be to just make a no-op function that fits the GDestroyNotify function signature, but it doesn't feel particularly elegant. Is there a better way of achieving this?
It's not documented, but it skips freeing when element_free_func is NULL. From the glib source code:
if (rarray->element_free_func != NULL)
{
for (i = index_; i < index_ + length; i++)
rarray->element_free_func (rarray->pdata[i]);
}
But if you want to stick to documented features, I think the no-op function is the expected solution.
I think this is intended, so perhaps this should be considered a documentation bug and you could submit a bug report about it.
I don't find any constructor that gives you a NULL-terminated array that doesn't require providing an element free function
Indeed, of the 8 (!) constructor functions in total for objects of this type, only g_ptr_array_new() does not take a pointer to a free function as an argument, and that function does not produce an array of the null-terminated flavor.
However, the docs do not specify the implications of providing a null pointer for the freeing function, and in practice, g_ptr_array_new() behaves as if you had passed such a null pointer. I don't necessarily think it's safe to rely on that, but it looks like you could get away with it for now. I would recommend documenting such an assumption if you make it.
One option would of course be to just make a no-op function that fits the
GDestroyNotifyfunction signature, but it doesn't feel particularly elegant.
I don't see why that seems inelegant to you. It seems natural to me.
Is there a better way of achieving this?
The way you propose seems fine to me, and it is the safest, most forward-looking option. However, if you can't bear to do that then it appears that using g_ptr_array_new_null_terminated() and passing NULL as the element freeing function probably would work too.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With