我超载了new
and delete
实现我自己的小对象/线程安全分配器。
问题是当我超载时new
,我不能使用new
不破坏普遍因果关系或至少不破坏编译器。我发现的大多数例子都在哪里new
超载,使用Malloc()
进行实际分配。但根据我对 C++ 的理解,没有任何用例Malloc()
at all.
有多个与此类似的答案,其中一些在 SO 之外的侵权行为较少:在什么情况下使用 malloc 和 new? https://stackoverflow.com/questions/184537/in-what-cases-do-i-use-malloc-vs-new
我的问题是,重载运算符时如何分配实际内存new
不使用Malloc()
?
(这更多的是出于好奇,尽量不要太认真地对待超载背后的原因;我有一个单独的问题!)
简短的回答:如果你不想要现有的malloc
,你需要实现你自己的堆管理器.
例如,堆管理器malloc
在Linux的glibc中,HeapAlloc
在Windows中,是一种用户级算法。首先,请记住,堆针对分配小尺寸对象(例如 4~512 字节)进行了优化。
如何实现自己的堆管理器?至少,您必须调用系统 API 在进程中分配内存块。有VirtualAlloc
对于 Windows 和sbrk
对于Linux。这些API分配大块内存,但大小必须是以下的倍数page尺寸。通常,x86 和 Windows/Linux 中的页面大小为 4KB。
获得一块页面后,您需要实现自己的算法,如何将大内存切成更小的请求。一个经典的(仍然非常实用)的实现和算法是dlmalloc
: http://g.oswego.edu/dl/html/malloc.html http://g.oswego.edu/dl/html/malloc.html
为了实现,您需要有多个用于记账的数据结构和多个用于优化的策略。例如,对于 16、20、36、256 字节等小对象,堆管理器维护每个大小的块的列表。所以,有一个列表的列表。如果请求的大小大于页面大小,那么它只是调用VirtualAlloc
or sbrk
。然而,有效的实施非常具有挑战性。您不仅必须考虑速度和空间开销,还必须考虑缓存局部性和碎片。
如果您对针对多线程环境优化的堆管理器感兴趣,请查看tcmalloc
: http://goog-perftools.sourceforge.net/doc/tcmalloc.html http://goog-perftools.sourceforge.net/doc/tcmalloc.html
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)