Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can you construct a NULL-terminated GPtrArray that doesn't have an element_free_func?

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?

like image 258
Newbyte Avatar asked Dec 03 '25 21:12

Newbyte


2 Answers

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.

like image 119
Barmar Avatar answered Dec 05 '25 12:12

Barmar


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 GDestroyNotify function 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.

like image 25
John Bollinger Avatar answered Dec 05 '25 12:12

John Bollinger



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!