编写自己的内存管理器

23

我想编写自己的内存管理器。目标语言是C++,该内存管理器的主要目的是帮助调试。它应该能够检测重复释放、内存覆盖等问题。当然,我也想学习关于内存管理方面的知识。

是否有人可以给我一些提示或资源,让我学会如何编写这样的内存管理器呢?

谢谢你的帮助。

9个回答

33

我认为这是一个非常有趣的项目,您可以从中学到很多东西。以下是有关内存管理主题的一些阅读材料。它涵盖了一些基本的内存管理知识,介绍了一个简单的malloc实现,然后涉及了一些更高级的主题。

内存管理详解

另外,既然您提到您想要制作一个对于调试有用的内存管理器,您可能想考虑阅读Memcheck / Valgrind开发人员编写的这篇论文(一个Linux上出色的内存调试器)。它详细介绍了他们如何在memchck中跟踪所有元数据(特定字节是否已定义,初始化等)。这篇论文内容有点复杂,但它是一份好的阅读材料,可以帮助您制作可伸缩和高效的动态内存检查器。

如何影子化程序使用的每个字节的内存


5
Dave Hanson的C界面与实现首先介绍了标准内存管理器,然后介绍了一些调试功能的内存管理器。这是学习和扩展的绝佳起点。
当然,如果您想要在运行中的C或C++程序中诊断内存问题,您应该使用valgrind

2

我看到一些示例使用C预处理器宏来实现malloc。这是一个聪明的想法。我相信你也可以写出类似的东西。

这里有一个看起来不错的起点。

http://stevehanov.ca/blog/index.php?id=10


1

有一个很棒的用Delphi编写的开源内存管理器:fastMM4。看一下它可能会很有价值。它支持许多你想要实现的功能,因此可能是一个很好的展示。


1

正如@Spence所说,这已经做过很多次了。但出于学习的目的,这还是相当有趣的。

我建议您看一下ld的--wrap Here,因为它非常有用。


这是拦截 new() 和 delete() 调用的非常好的第一步。请参阅 Falaina 在检测数组越界复杂性方面的帖子 - 这是一个不同的问题。 - Matt

0

你可以使用malloc和free来实现大部分功能 - 实际上,即使不必要,很多C++内存管理器也是这样实现的。

你可以从一个简单的实现开始,它维护所有分配和释放的日志,但将常规的分配/释放转发到malloc和free。显然,简单的实现也不应该使用new/delete...

所以,你可以:

  • 设计数据结构来记录分配和释放
  • 大部分采用"C风格"实现,尽管你可以使用placement new来确保调用构造函数
  • 实现全局new和delete作为包装器,首先在上述数据结构中记录访问,然后将调用转发到malloc或free

0

我认为你可以从一个智能指针实现开始,它在后台使用基本的引用计数。这些是内存管理的基础,可以让你入门。然后,你可以使用自己的实现来创建更高级的内存管理器。


0
"

“Electric fence”是一个基本的起点,可能会有所帮助。它本质上具有自定义的malloc和free实现,提供了调试功能。

然而,据我所知,它并没有集成到C++的new/delete运算符中,但是提供自定义的全局new/delete实现,以便推迟到电子围栏例程,这不会太难。

"

-2

你用的是什么平台?在你尝试重新实现整个系统之前,想知道是否可以使用valgrind或lint来帮助你解决问题?


2
当然可以 - 但我不会学到任何东西。 - Tobias Langner
使用Valgrind来查找内存泄漏,你不会学到任何编码技巧吗?如果你正在使用有缺陷的对象销毁方式(或者根据你的平台释放),那么你很快就会发现。我确实看到了实现堆等的价值,以了解它是如何完成的,但这本身需要大量的努力才能做到正确,并且当你遇到问题时,它会留下更多需要调试的东西。 - Spence
如果我是为了工作而这么做 - 你完全正确。没有必要重新发明轮子。但是为了乐趣和学习,仅仅使用valgrind并不能给人深入的洞察和乐趣。但我欣赏你的思维方式,Spence。如果你开始编程,首先要做的事情就是检查是否有人已经完成了你的工作。大多数情况下,他们做得比你好。 - Tobias Langner
玩弄API并没有什么不好的。如果我没有研究SqlBulkCopy,那么我就无法解决工作中的一个难题。如果你在工作中遇到了内存泄漏问题,我想确保你知道valgrind带来的乐趣(或痛苦...)。 - Spence

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接