【问题标题】:How to use std::allocator in my own container class如何在我自己的容器类中使用 std::allocator
【发布时间】:2011-01-31 08:34:13
【问题描述】:

我正在尝试编写一个使用 STL 分配器的容器类。我目前做的是拥有一个私人会员

std::allocator<T> alloc_;

(稍后将对其进行模板化,以便用户可以选择不同的分配器)然后调用

T* ptr = alloc_.allocate(1,0);

获取指向新分配的“T”对象的指针(并使用 alloc_.construct 调用构造函数;请参阅下面的答案)。这适用于 GNU C++ 库。

但是,在 Solaris 上使用 STLPort,这无法正确处理并导致各种奇怪的内存损坏错误。如果我改为这样做

std::allocator_interface<std::allocator<T> > alloc_;

然后一切正常。

使用 stl::allocator 的正确方法是什么? STLPort/Solaris版本用g++编译失败,但是g++对吗?

【问题讨论】:

  • 标准库中没有名为allocator_interface的东西。

标签: c++ g++ memory-management stlport


【解决方案1】:

您需要使用分配器进行分配和构造。像这样的:

T* ptr = alloc_.allocate(1,0);
alloc_.construct(ptr, value);

如果你没有从一个正确构造的对象开始,很多事情都会被彻底破坏。想象一个std::string 被分配但没有被构造。当您尝试分配给它时,它会首先尝试通过释放一些数据来清理其旧内容,这些数据当然是堆中的垃圾值并崩溃。

【讨论】:

  • 是的,我知道,我确实这样做了,尽管我使用了placement new而不是std::allocator::construct(这可能不推荐,所以我现在改变了)。然而,事实证明 STLPort 4.x 也不知道 std::allocator::construct ...
  • 如果 STLPort 没有std::allocator&lt;T&gt;::construct 那么它就坏了,即使使用它也不要费心。我可以肯定地告诉你 5.1.5(我安装的版本确实有它并且工作正常)。
  • 我想满足我的好奇心,STLPort 4.x 确实具有符合std::allocator的适当标准。在 4.6 中,construct 函数位于 stlport/stl/_alloc.h 的第 365 行。如果它不起作用,则说明您的安装不正确。
  • 构造在 C++ 20 中被弃用
【解决方案2】:

您可能想要做的是拥有自己的自定义allocator,您可以使用它来查看标准容器如何与分配器交互。 Stephan T. Lavavej 发布了一个漂亮、简单的帖子,名为 mallocator。将其放入使用各种 STL 容器的测试程序中,您可以轻松查看标准容器如何使用分配器:

并非mallocator 中的所有接口函数(例如construct()destroy())都配备了跟踪输出,因此您可能希望将跟踪语句放在其中以便更轻松地查看标准容器可能无需借助调试器即可使用这些功能。

这应该让您很好地了解您的容器可能会如何使用自定义 allocator

【讨论】:

  • 不幸的是它没有追踪construct 这是他未能使用的功能:-/
  • 是的(我在回答中提到了这个缺点),我打算让我的回答或多或少成为您回答的侧边栏,直接指出问题。 Lavavej 发布了mallocator 作为自定义分配器的简单示例。我建议它也可以用作深入了解容器如何使用分配器的简单方法,但可能需要进行一些小的修改以改进跟踪。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-23
  • 2013-05-06
  • 1970-01-01
  • 1970-01-01
  • 2012-01-31
相关资源
最近更新 更多