在 C/C++ 之中内存泄漏一直是个老大难问题,但索性用于辅助定位查找得解决方案也不少,虽然没那么详细,但总比没有要好的多。
有一些是用三方工具来查得,但这个需要编译debug,带上符号信息得版本才可以,就很麻烦,而且只能查 new 传入符号信息得数据,有一些是hook形式,需要在通过这些工具引导运行,反正不好用就是了。
微软自己在VC++上面倒是弄个很牛逼的诊断工具,这个情况允许还是可以用它得,但这种东西还是自己弄比较靠谱一些。
我们在构建C/C++工程底层框架得时候,就必须确保能够正确记录不管是 “类型信息”,还是“源文件、行号”这些信息。
但通常只需要能捕获类型信息就可以,毕竟看类型得符号表信息就知道是那个地方new分配出来的,在关闭服务器得时候把每个类型信息得分配都统计下计数,看退出程序时候打印出来得报表就知道那些C/C++资源分配是出现泄漏了。
对于句柄泄漏这个可以用pc huter、process explorer 等内核级工具来查,这个简单,Windows 平台上查资源泄漏还是很方便得。
当然还有就是在每次分配的内存上面加一个链表头,分配跟释放来动态管理内存分配得链,在链头上加上行号、跟文件名等信息。
本文用最简单的方法,直接放在set里面就可以,因为存储得是类型信息,因为我这边主要是用模板函数来实现new/delete、而不是用宏,不太容易获取到调用该函数得当前行号、文件名得信息。
示意:
static ppp::unordered_map<void*, const char*> malloc_objects_;static std::mutex malloc_objects_syncobj_;void malloc_object_free(void* p) {std::lock_guard<std::mutex> scope(malloc_objects_syncobj_);auto tail = malloc_objects_.find(p);auto endl = malloc_objects_.end();if (tail != endl) {malloc_objects_.erase(tail);}}void malloc_object_add(void* p, const char* n) {std::lock_guard<std::mutex> scope(malloc_objects_syncobj_);malloc_objects_[p] = n;}void malloc_object_printf() {ppp::string result;ppp::unordered_map<ppp::string, int> counters;for (auto [_, key] : malloc_objects_) {counters[key]++;}for (auto [key, value] : counters) {result += key + "; " + stl::to_string<ppp::string>(value) + "\r\n";}printf("\r\n\r\n\r\nMEMORY DUMP: %s", result.data());}
退出程序得时候调用下,把当前内存对象都打印下,看看那些是产生了泄漏了,这个可以做成一个接口,如果是做服务器程序得话,方法这块都差不多,内存泄漏不这么搞,纯靠猜是很难解决问题得,也没得效率。