(四) 兵马未动,粮草先行——想一想检测内存泄漏
“兵马未动,粮草先行”可能不恰当,说的就是那么个意思。
B站上有所谓“5种内存泄漏检测的方式,让你重新理解内存”,使用宏定义替换、dlsym hook、bpftrace,看了会觉得“哦,原来是这样做的”,但动手去写的时候会发现还是不知道怎么做。
C/C++检测内存泄漏工具有强大的valgrind。
Valgrind对GTK失效
如果不使用额外规则,直接使用valgrind对gtk应用程序去检测,会发现提示数量庞大的内存泄漏。
老外也在问为什么,甚至还有人在gitlab上官方gtk仓库中提问,得到的回复竟是“你不看gnome文档吗”,似乎有轻视、厌烦之意。
可实际上呢,https://developer.gnome.org/documentation/tools/valgrind.html 是说了,可在小版本上仍是未全部包含。
添加 --suppressions=/usr/share/glib-2.0/valgrind/glib.supp --suppressions=/usr/share/gtk-4.0/valgrind/gtk.supp 参数去检测gtk4-demo,依旧提示上万个内存泄漏。
添加--gen-suppressions=all来生成规则,--log-file=写入文件,(自己还特意写了个程序来从log文件中提取{}规则)。

再--suppressions=加上对gtk4-demo生成的规则,对自己的程序去检测,依旧吓一跳。
放弃GTKMM,自己封装
GTK这么傲慢,就让它傲慢着。既然GTK使用的是C,那就自己去用C++封装。
在这之上,只要自己不再添加C代码,那么只要做C++内存泄漏检测即可。
最简单的方式就是重载new delete,unique内部也是使用的new、delete。new/delete也是用的malloc/free。
重载new delete new[] delete[],然后弄个双向链表,OK,简单的实现与测试就有了。






测下std::unique_ptr,再测下new一个然后没有对应delete释放

剩下GTK的内容
至于GTK的内容,还没搞懂,但某个国外网站上某个问题的讨论上,老外有说一句,只要不是toplevel的window都得自己手动释放。
看Getting Started with GTK,应该是app管理appwindow,通过set_child等方式使得各部件指针形成以appwindow为root的child/parent树,只要app释放,就应该会同时“删除”部件。
status = g_application_run (G_APPLICATION (app), argc, argv);
g_object_unref (app);
(其实也没有其他函数可以删除部件了(?))
但程序退出,相应内存资源交由系统去释放,故而valgrind认为相应内存“泄漏”了。