Search code examples
gtk3glib

g_object_set_data has memory holes


I'm making a GTK3 application and I use g_object_set_qdata on a GtkListBoxRow for searching purpose.

I use this code :

GArray      *complib;
#define row_get_entry(row) (ElcCompLibEntry*)g_object_get_qdata(G_OBJECT(row),registryquark)
GtkWidget* elc_registry_listbox_make_item(ElcCompLibEntry* curritem)
{
  /* I remove UI creation */
  GtkWidget* intermediate = gtk_list_box_row_new();
  gtk_container_add(GTK_CONTAINER(intermediate),GTK_WIDGET(mainbox));
  gtk_widget_show_all(GTK_WIDGET(intermediate));
  g_object_set_qdata(G_OBJECT(intermediate),registryquark,curritem);
  return intermediate;
};
  static GtkWidget* saved = NULL;
  GtkWidget* new=elc_registry_listbox_make_item(entry);
  gtk_container_add(GTK_CONTAINER(listbox->real_listbox),new);
  if (saved)
    g_debug("saved entry is at position %d",((gintptr)row_get_entry(saved)-(gintptr)complib->data)/sizeof(ElcCompLibEntry));
  saved=new;
  g_debug("entry is at position %d",((gintptr)row_get_entry(new)-(gintptr)complib->data)/sizeof(ElcCompLibEntry));

The output of my program :

** (elc:9906): DEBUG: 18:51:10.623: entry is at position 0

** (elc:9906): DEBUG: 18:51:10.625: saved entry is at position -14015
** (elc:9906): DEBUG: 18:51:10.625: entry is at position 1

** (elc:9906): DEBUG: 18:51:10.627: saved entry is at position 32
** (elc:9906): DEBUG: 18:51:10.627: entry is at position 2

** (elc:9906): DEBUG: 18:51:10.629: saved entry is at position 2
** (elc:9906): DEBUG: 18:51:10.629: entry is at position 3

** (elc:9906): DEBUG: 18:51:10.631: saved entry is at position 25921
** (elc:9906): DEBUG: 18:51:10.631: entry is at position 4

ElcCompLibEntry is a simple struct. g_object_set_qdata_full is just corrupting older datas, the quark is initialized, even when running it in the main thread I got the same result (only the saved entry is at position 2 is constant).

Could someone help find the root of the problem and/or send me to the relevant documentation ?

Thank you for your time !


Solution

  • Per https://developer.gnome.org/glib/stable/glib-Arrays.html#GArray,

    The data may be moved as elements are added to the GArray.

    It's hard to tell without seeing the code that creates and appends to complib, but complib->data is not constant and your pointers stored in qdata are probably being invalidated when the array is resized.

    To prevent this, try creating the array with g_array_sized_new() preallocating the number of elements you need.