likern
likern

Reputation: 3964

Extract pointer to data from GPtrArray

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

Answers (3)

Philip Withnall
Philip Withnall

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

Paul Childs
Paul Childs

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

ctn
ctn

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

Related Questions