Dans cet article, je parlerai de mes mésaventures avec les pointeurs intelligents shared_ptr. Après avoir implémenté la génération de niveau supérieur dans mon jeu Death-Mask, j’ai remarqué un souvenir fuir . Chaque nouveau niveau donnait une augmentation de + 1 mégaoctet à la RAM consommée. Il est évidemment que certains objets sont restés en mémoire et ne l’ont pas libéré. Pour corriger ce fait, il a fallu mettre en œuvre la bonne mise en œuvre des ressources lorsque le niveau est surchargé, ce qui n’a apparemment pas été fait. Depuis que j’ai utilisé des pointeurs intelligents, il y avait plusieurs options pour résoudre ce problème, la première impliquait une révision manuelle du code (longue et ennuyeuse), tandis que la seconde impliquait de rechercher les capacités du débogueur lldb et le code source de libstdc++ pour la possibilité de suivre automatiquement changements de compteur.
Sur Internet, tous les conseils se résumaient à réviser manuellement le code, à le corriger et à se frapper avec des fouets après avoir trouvé la ligne de code problématique. Il a également été proposé d’implémenter son propre système de travail avec la mémoire, comme le font tous les grands projets développés depuis les années 90 et 2000, avant l’arrivée des pointeurs intelligents dans le standard C++11. J’ai essayé d’utiliser des points d’arrêt sur le constructeur d’une copie de tous les shared_ptrs, mais après plusieurs jours, rien d’utile ne s’est produit. Il y avait une idée pour ajouter la journalisation à la bibliothèque libstdc++, mais les coûts de main d’œuvre se sont avérés monstrueux.

Cowboy Bebop (1998)
La solution m’est soudainement venue à l’esprit : suivre les modifications apportées à la variable privée shared_ptr – use_count. Cela peut être fait en utilisant les points de surveillance intégrés dans lldb. Après avoir créé un shared_ptr via make_shared, les modifications apportées au compteur dans lldb peuvent être suivies à l’aide de la ligne :
regarder set var camera._M_refcount._M_pi->_M_use_count
Où « caméra » ; il s’agit d’un objet shared_ptr dont l’état du compteur doit être suivi. Bien sûr, les composants internes de shared_ptr varieront en fonction de la version de libstdc++, mais le principe général peut être compris. Après avoir installé le point de surveillance, nous lançons les applications et lisons le stacktrace de chaque changement de compteur, puis nous regardons le code (sic !), trouvons le problème et le réparons. Dans mon cas, les objets n’ont pas été libérés des tables de cache et des tables de logique de jeu. J’espère que cette méthode vous aidera à gérer les fuites lorsque vous travaillez avec shared_ptr et j’aimerai encore plus cet outil de mémoire. Bon débogage.