G_object_set_qdata a la mémoire courte

gtk
Tags: #<Tag:0x00007f092bef2578>

#1

Bonjour,

Je développe un programme sous GTK+ et j’utilise cette API pour stocker des infos sur des GtkListBoxRow.
J’ai une ligne :
g_object_set_qdata(G_OBJECT(row),registryquark,curritem);
Ici curritem est un pointeur sur une structure maison qui contient un char** utilisé pour ma fonction de recherche.

Plus tard dans mon code fais un
g_object_get_qdata(G_OBJECT(row),registryquark);
Et là, le drame… parfois je ne retrouve pas le pointeur que je lui ai mis avant.
En fait, g_object_set_qdata corromps immédiatement les anciennes valeurs des autres row !

Je précise que je construis mes row dans le même thread séparée, la fonction de filtre s’exécute alors une fois correctement, mais c’est dès l’itération suivante de ma boucle que la corruption a lieu.

Quelqu’un peut-il me conseiller ?


#2

Tu as essayé de tracer ton programme avec GDB en surveillant les valeurs de tes arguments.

J’avais fait un projet perso en C/GTK+ et je me souviens d’un bug où tout crashait après une manip dès que je bougeais la souris. Je ne me souviens plus de la cause mais GDB m’avait sorti d’affaire. Je crois que j’avais pas passé le bon pointeur, du coup l’adresse changeait au lieu de la valeur (ça n’a pas de sens ce que je raconte mais c’était un truc puant comme ça). Bref, regarde bien les signature de tes méthodes, on sait jamais.
L’autre truc que je rencontrais souvent c’était les double-free:

  • tu fais un free(pointeur)
  • ton code continue de tourner et la mémoire qu’utilisait le pointeur est recyclée. De nouvelles données y sont écrites
  • plus loin dans ton code, tu refais un free(pointeur) par erreur, ce qui efface les données innocentes. Ça peut aussi être du code qui est effacé, ce qui produit des bugs assez violents.

Je ne suis plus très frais avec le C mais je crois que j’avais pris l’habitude setter mes pointeurs à NULL après un free() mais il y a surement plus rusé.
Initialiser ses variables aussi. Un int est initialisé avec la valeur qui se trouve en mémoire à ce moment là. Souvent 0, mais pas toujours. Attaquer une boucle en pensant que sa variable fraichement déclarée est définie à 0 ça crée des bugs aléatoires.
À défaut de GDB, un bon vieu printf de tes pointeurs pour voir si tout roule.
N’hésite pas à poster du code aussi.

P.S: Ah mais attends! ListBox* ce ne sont pas des nouvelles méthodes visant à remplacer les Tree/ListModel/View/Store ? J’ai vu passer un blog ou je ne sais quoi d’un gars qui avait joué avec et finalement était revenu sur une List traditionnelle (performances pas top)

Edit: J’ai retrouvé le post. C’est l’auteur d’un journal linuxfr sur GTKTree/List qui commente sur ListBox https://linuxfr.org/nodes/116386/comments/1762103
Si tu es l’auteur, alors je ne t’apprends rien, désolé.


#3

Salut,

Merci pour ta réponse, en fait j’utilisais un GArray pour stocker mes donnés, du coup lorsqu’il grandit et fait un realloc, les donnés sont parfois déplacées… mais pas les pointeurs dans les qdata.