The Standard Librarian :A Debugging Allocat…

2008-02-23 05:32:26来源:互联网 阅读 ()

新老客户大回馈,云服务器低至5折

The Standard Librarian :A Debugging Allocator
Matt Austern
http://www.cuj.com/experts/1912/austern.htm?topic=experts
--------------------------------------------------------------------------------
C 标准库中的Allocator有一个复杂而低层次的接口[注1]。和new和delete不同,他们将内存分配和对象构造解耦。和malloc和free不同,他们需要您明确正在分配的内存的数据类型和对象数目。
通常,这不成为问题。Allocator拥有低层次的接口是因为他们是低层次的概念:他们通常隐藏在容器类内部,而不属于普通用户的代码。然而,有时您可能不得不关心allocator:当您自己写一个新的容器类的时候。Allocator比new/delete难用多了,因此,更容易发生错误。假如您写的代码不得不使用allocator,如何确保代码正确?运行期的测试不能证实不存在错误,只能证实错误的存在。尽管如此,测试还是很重要--您越快发现bug,他就越早被修正。
任何的标准容器类都接受一个allocator类作为其模板参数;这个参数有一个默认值,比如std::vector<int>是vector<int,std:: allocator<int> >的简写。假如我们写了一个有额外正确性检查的alocator类,那就能够用他代替std::allocator<int>来作为vector的第二模板参数。假如没有bug的话,vector的行为将会和以前相同。(当然,除了额外的检查将使他变慢。)
这篇文章将展示这样一个debugging allocator类。他在其适用范围内是有价值的,并且实现他也是使用allocator的一个有趣练习。
测试
我们想检查什么种类的错误?最重要的是:
l 传给的deallocate()的内存确实是这个allocator分配的。
l 当deallocate()一块内存时,归还了和分配时相同的字节数。(和malloc和free不同,allocator不为自己记录这些信息。)
l 正deallocate()的内存,其类型和分配时相同。(虽然 allocator将内存分配和对象构造解耦了,但内存仍然是为某个特定数据类型分配的。)
l 当在一块内存中写入数据时,我们不会越界。
l 从不试图在同一位置构造两个对象,并且也不会试图销毁同一对象两次。
l 当deallocate()一块内存时,确保先销毁了其中的任何对象。
如我们将要看到的,我们的debugging allocator不会满足任何需要。我们能检查其中的一部分错误,而不是全部。
在debugging allocator背后的主意很简单[注2]:每当allocate()一块内存时,多分配一些,并在最初几个字节中记录一些额外信息。用户看不到这块debug区域;我们传给用户的指针指向在此之后的内存。当传回给我们一个指向我们分配的内存块的指针时,我们能够减小其值以查看debug区域,并确认内存块是被正确使用的。
这样的设计有两个隐藏问题。首先,不可能相当可移植地实现他。我们必须保持对齐:假设用户数据的地址需要对齐,我们保留了一些字节而还要维持对齐。我们如何知道该加多少?理论上,我们无法知道;语言没有提供判断对齐需要的机制。(也许这将会增加到未来的标准中)。实践中,他不是个严重的可移植性议题:在double word上对齐任何东西,在现在绝大部分平台上都足够好了,并且在需要更严格的平台上作相应修改也很容易。

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇: 为C 标准库容器写自己的内存分配程式

下一篇: 键树算法的实现