(四) 兵馬未動(dòng),糧草先行——想一想檢測(cè)內(nèi)存泄漏
????“兵馬未動(dòng),糧草先行”可能不恰當(dāng),說的就是那么個(gè)意思。
????B站上有所謂“5種內(nèi)存泄漏檢測(cè)的方式,讓你重新理解內(nèi)存”,使用宏定義替換、dlsym hook、bpftrace,看了會(huì)覺得“哦,原來是這樣做的”,但動(dòng)手去寫的時(shí)候會(huì)發(fā)現(xiàn)還是不知道怎么做。
????C/C++檢測(cè)內(nèi)存泄漏工具有強(qiáng)大的valgrind。
Valgrind對(duì)GTK失效
????如果不使用額外規(guī)則,直接使用valgrind對(duì)gtk應(yīng)用程序去檢測(cè),會(huì)發(fā)現(xiàn)提示數(shù)量龐大的內(nèi)存泄漏。
????老外也在問為什么,甚至還有人在gitlab上官方gtk倉(cāng)庫(kù)中提問,得到的回復(fù)竟是“你不看gnome文檔嗎”,似乎有輕視、厭煩之意。
????可實(shí)際上呢,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 參數(shù)去檢測(cè)gtk4-demo,依舊提示上萬個(gè)內(nèi)存泄漏。
????添加--gen-suppressions=all來生成規(guī)則,--log-file=寫入文件,(自己還特意寫了個(gè)程序來從log文件中提取{}規(guī)則)。

再--suppressions=加上對(duì)gtk4-demo生成的規(guī)則,對(duì)自己的程序去檢測(cè),依舊嚇一跳。
放棄GTKMM,自己封裝
????GTK這么傲慢,就讓它傲慢著。既然GTK使用的是C,那就自己去用C++封裝。
????在這之上,只要自己不再添加C代碼,那么只要做C++內(nèi)存泄漏檢測(cè)即可。
????最簡(jiǎn)單的方式就是重載new delete,unique內(nèi)部也是使用的new、delete。new/delete也是用的malloc/free。
????重載new delete new[] delete[],然后弄個(gè)雙向鏈表,OK,簡(jiǎn)單的實(shí)現(xiàn)與測(cè)試就有了。






測(cè)下std::unique_ptr,再測(cè)下new一個(gè)然后沒有對(duì)應(yīng)delete釋放

剩下GTK的內(nèi)容
????至于GTK的內(nèi)容,還沒搞懂,但某個(gè)國(guó)外網(wǎng)站上某個(gè)問題的討論上,老外有說一句,只要不是toplevel的window都得自己手動(dòng)釋放。
????看Getting Started with GTK,應(yīng)該是app管理appwindow,通過set_child等方式使得各部件指針形成以appwindow為root的child/parent樹,只要app釋放,就應(yīng)該會(huì)同時(shí)“刪除”部件。
????status = g_application_run (G_APPLICATION (app), argc, argv);?
????g_object_unref (app);
(其實(shí)也沒有其他函數(shù)可以刪除部件了(?))
但程序退出,相應(yīng)內(nèi)存資源交由系統(tǒng)去釋放,故而valgrind認(rèn)為相應(yīng)內(nèi)存“泄漏”了。