类似于矢量的容器,可以使存储相互连续的实例?

Dis*_*ame 4 c++ memory-management stl vector c++11

我需要一个API尽可能接近std :: vector的容器类(除了没有重新分配),但是可以指定从现有缓冲区分配其元素的存储(而不是其成员变量,如size),以便我可以将所有向量的元素保存在连续的缓冲区中.也就是说,一个向量的.end()指向缓冲区中与下一个向量相同的元素.

我不知道我是否可以简单地使用带有std :: vector的自定义分配器,因为我无法找到有关是否为整个类分配存储的信息,包括大小和指针数据成员(在这种情况下我不能使用这种方法),或者只是它所拥有的数据元素(在这种情况下我可以使用它).

我只需要分配一个实例的存储空间,因此重新分配没有问题.我在这里发帖,看看是否已经发布了这样的容器,而不是从头开始重新实现大多数带有迭代器的std向量接口.


更新:我取消选中已发布的答案,因为它在Visual C++ 2012中的调试模式下不起作用.示例T= = float:

template<class T>
inline typename ContigAlloc<T>::pointer ContigAlloc<T>::allocate(std::size_t n)
{
    std::cout << "Alloc " << n << "; type match: " << std::boolalpha << std::is_same<T, float>::value << std::endl;
    return reinterpret_cast<T *>(_buff.alloc(T * sizeof(n)));
}

template<class T>
inline void ContigAlloc<T>::deallocate(T *p, std::size_t n) // TODO: noexcept when VC++2013
{
    std::cout << "Deall " << n << "; type match: " << std::boolalpha << std::is_same<T, float>::value << std::endl;
    _buff.dealloc(p, T * sizeof(n));
}
Run Code Online (Sandbox Code Playgroud)

测试:

std::vector<float, ContigAlloc<float>> vec;
vec.push_back(1.1f);
vec.push_back(1.9f);
Run Code Online (Sandbox Code Playgroud)

发布版本的结果很好:

Alloc 1; type match: true
Alloc 2; type match: true
Deall 1; type match: true
Deall 2; type match: true
Run Code Online (Sandbox Code Playgroud)

调试构建的结果不正确:

Alloc 1; type match: false
Alloc 1; type match: true
Alloc 2; type match: true
Deall 1; type match: true
Deall 2; type match: true
Deall 1; type match: false
Run Code Online (Sandbox Code Playgroud)

在第一次调用中allocate(),T=_Container_proxy

How*_*ant 7

分配器仅用于为元素分配存储空间.您可以使用自定义分配器来实现此目的.

Jon在下面的评论中对此表示纠正.

我认为可以实现一致性vector,以便它将所有内容存储在堆上,除了指针.堆上的东西可以是3个指针,加上分配器(如果没有分配器没有被优化掉),或1个指针,大小和容量(以及可能优化的远离分配器).

实际上,它的每一个实现std::vector都以任何形式发布,包括:

  • 生命值
  • SGI
  • libstdc ++(gcc)
  • libc ++(llvm)
  • Dinkumware的
  • 微软
  • 流氓波
  • 的CodeWarrior
  • STLPort的
  • 我确定我忘记了其他一些人......

已将所有支持成员放在向量类本身中,并仅将分配器用于分配数据.除此之外似乎没什么动力.

所以这是事实上的标准,而不是官方标准.根据上面的历史,这是一个非常安全的.

请注意,人们无法做出相同的声明string,其概念上具有相同的布局.C++ 11实现string通常会使用"短字符串"优化,其中分配器根本不用于"短"字符串,而是将值嵌入字符串类中.vector23.2.1一般容器要求[container.requirements.general]/10 有效禁止这种优化:

(除非另有说明)否则swap()函数会使引用正在交换的容器元素的任何引用,指针或迭代器无效.