内存泄漏:排查了三天,发现是一个delete忘在循环里了
上篇聊了new/delete,有人后台说想看内存泄漏。来了。这个话题在机器人开发里太重要了,因为机器人程序是长时间运行的——一跑就是几天、几周、甚至几个月。内存泄漏这种问题,在短时间的测试里根本发现不了,等上了产线才爆出来。讲个真实的故事。去年帮朋友排查一个bug。他们做AGV的,机器人跑得好好的,大概每跑6个小时就崩一次。重启之后又正常了,再过6小时又崩。我接过去看,第一反应是内存泄漏。用valgrind跑了一下,果然——每处理一帧激光雷达数据,就泄漏4KB内存。原因是什么呢?一个同事在解析雷达数据的时候,每帧都new了一个缓冲区,但在某个异常分支里忘了delete。void processLidarScan(const uint8_t* raw_data, int size) { uint8_t* buffer = new uint8_t[size]; if (size MIN_SIZE) { return; // 这里直接return了,buffer没delete! } // 正常处理... delete[] buffer; }size MIN_SIZE的时候直接return了,buffer没释放。每帧泄漏一次,6小时下来内存就爆了。修复很简单,加一行delete就行。但这种bug,在代码review的时候很难发现,因为逻辑上是"正确"的——异常数据确实应该提前返回。而且测试的时候,异常数据出现的频率不高,偶尔泄漏一点根本看不出来。内存泄漏到底是什么?