Reputation: 3964
I'm using GPtrArray
structure to hold pointers to chunks of dynamically allocated memory. As I need as simple as possible and correct freeing of memory I set callback g_ptr_array_new_with_free_func ()
which will free one element of pointer array. Thus when I call g_ptr_array_free()
for all elements of array is called callback which correctly freeing allocated memory. Here is some pseudo code which describe problem:
...
GPtrArray *stack = g_ptr_array_new_with_free_func(pt_free_stack_element);
if(...) {
...
g_ptr_array_free(stack);
...
}
if(interrupt) {
// Here I need to do something like pop() for stack
// I want to get pointer at some allocated element,
// and remove it from stack, but without freeing
// memory of this element
}
The problem is that documentation says that any g_ptr_array_remove()
, g_ptr_array_remove_index()
, g_ptr_array_remove_fast()
, g_ptr_array_remove_index_fast()
destroy element's memory by calling callback if it's set. As you see I have set callback.
Well, general how I could do that? How can I get pointer to the element like g_ptr_array_index()
with deleting any mention of this pointer from array, but without freeing element's memory?
Upvotes: 0
Views: 1027
Reputation: 5733
Since GLib 2.58, you can use g_ptr_array_steal_index()
, which was added for precisely this reason.
p = g_ptr_array_steal_index (stack, i);
…
pt_free_stack_element (p);
If the array doesn’t need to stay in order, you can use g_ptr_array_steal_index_fast()
instead, to make things a bit faster.
Upvotes: 1
Reputation: 230
It is not necessarily true that the callback function will destroy the memory. If your pointers are to GObjects, GArrays, etc and use a destroy function of a *_unref call then it will only destroy memory that has a ref count of zero. You can thus pop from your stack using a *_ref call to ensure it is not destroyed. No need for any messy storing and overwriting of free functions, and it's a lot neater and memory safe.
Upvotes: -1
Reputation: 2930
You can do:
g_ptr_array_set_free_func(stack, null);
p = g_ptr_array_index(stack, i);
g_ptr_array_remove_index(stack, i);
g_ptr_array_set_free_func(stack, pt_free_stack_element);
Upvotes: 1