35 | 发现和识别内存问题:内存调试实践
该思维导图由 AI 生成,仅供参考
场景
内存调试原理
- 深入了解
- 翻译
- 解释
- 总结
本文深入介绍了内存调试的实践方法和原理,提出了自行编写内存调试工具的建议。作者详细介绍了内存调试的基本原理,包括记录内存分配相关信息、检查内存匹配情况以及根据不同使用场景记录不同信息等。文章还介绍了基于“上下文”的内存调试工具,并给出了一个小小的内存调试工具的实现示例。在实现示例中,作者讨论了在程序退出时进行内存泄漏检查的典型应用,并介绍了一个小细节,即为`context_stack`准备了一个独立的分配器,以避免内存占用被记录到“当前”上下文中。总的来说,本文通过深入浅出的方式介绍了内存调试的实践方法和原理,对读者进行了技术上的指导和启发。文章内容涵盖了内存调试的基本原理、自行编写内存调试工具的建议以及实现示例,对读者进行了全面的技术指导。值得一提的是,文章最后还提供了一个课后思考部分,引导读者进一步探索实际实现中增加的复杂性。
《现代 C++ 编程实战》,新⼈⾸单¥59
全部留言(6)
- 最新
- 精选
- 转遍世界你好吴老师,您这个内存调试实践代码主要是针对内存泄漏和重复释放的问题。但工作中基本用的是智能指针,这些问题出现的可能性不大。工作中主要的内存问题是野指针问题,比如数组越界访问,迭代器失效后访问非法内存,主要还是访问非法内存问题居多,请问如果想检查这类内存错误可以用代码去检测吗?还怎么去实现?
作者回复: 这类问题没什么代码检测的好办法。只能使用外部工具,如 Address Sanitizer 和 Clang-Tidy。目前主要还是靠前者这样的运行期工具。
2024-01-15归属地:江苏1 - H X请问 1 .valgrind的内存检测工具 memcheck 和massif 这两个,能否根据我自己的项目 对其源码进行修改。最小影响的 检测我的项目中内存泄漏问题。2、cpp中没有jvm的GC。我用valgrind memcheck查出很多 still reachable。我理解这是内存碎片(vector和string频繁增删数据导致的)针对still reachable 有好的办法解决吗?多谢老师
作者回复: Valgrind 使用 GPL v2 发布,显然你可以自己去修改它的源代码。 still unreachable 我怀疑是真正的泄漏而不是内存碎片。你可以换用其他的内存检测工具试一下。C++ 理论上现在应该不容易产生内存泄漏了,如果你不用有所有权的裸指针的话——确实很少再有理由用了。
2022-05-251 - Geek_595be5请问上面示例中get_current_context函数返回的是引用会不会不安全,毕竟因stack实现不同,可以通过pop、push对之前的引用造成内容擦写
作者回复: 在目前我的用法下,拿到引用立即调用另一个函数(而不是保存下来),是没有问题了。这里主要关注性能,而不是防误用。
2023-08-30归属地:新加坡 - tonyconvert_use_ptr中计算usr_ptr的长度是否在任何情况下都没有问题?比如分配的内存大小正好是对齐的且后续内存地址中的内容也不为0。谢谢老师。 “auto offset = static_cast<byte*>(usr_ptr) - static_cast<byte*>(nullptr);”
作者回复: 我没看懂你的问题。分配的内存大小是强制对齐的,也跟“后续内存地址中的内容”是不是0完全没有关系……
2023-03-30归属地:安徽 - awmthink吴老师,请问:memory_trace里 “使用 RAII 计数对象来尽可能延迟对 check_leaks 的调用” 怎么理解呢?我看代码时,是把check_leaks调用放在了一个static对象的析构里,和全局对象invoke_check_leak相比,行为有什么不同吗?(防止有其他编译模块定义的全局对象生命周期比invoke_check_leak更长吗?)
作者回复: 不同翻译单元里的全局/静态对象的析构顺序没有保证。文中的技巧可以保证析构发生在所有包含了这个头文件的源文件里的全局/静态对象的析构之后。
2023-02-15归属地:广东 - ericaaa老师您好,我对free_mem最后一行free(ptr)有一些不大理解。这里的ptr类型是alloc_list_t*,这样是否只释放了head所占的memory而没有释放user object所占的memory呢?
作者回复: free 的参数类型是 void*,非强类型。它不管你内存是怎么使用的:只要你给 free 的是 malloc 得到的指针并之前没有释放过,操作就应该成功——把整个 malloc 分配的内存块释放掉。
2022-05-27