为字符串向量预分配内存(C++ vector<string>)

Posted

技术标签:

【中文标题】为字符串向量预分配内存(C++ vector<string>)【英文标题】:Preallocate memory for vector of strings (C++ vector<string>) 【发布时间】:2011-04-04 19:37:42 【问题描述】:

在 C++ 中,是否有一种聪明(即快速)的方法来为字符串向量预分配内存,以便每个元素都有一些最小大小?我的幼稚方式如下:

vector<string> my_string_vector;
my_string_vector.resize(1000);
for (unsigned int ui=0; ui<1000; ui++)
   my_string_vector[ui].reserve(1024);

非常感谢,

亚当

【问题讨论】:

【参考方案1】:

没有快速的方法可以做到这一点。您可以获得更少的代码行数,但您仍然需要为std::vector 中的每个std::string 调用一次reserve

如果你愿意走这条路,我相信EASTL 或Boost.Pool 可能会有所帮助。

【讨论】:

【参考方案2】:

一次预分配所有这些内存的唯一方法是实现自己的分配器,就像这样(代码不完整,显然分配器有更多需要支持的成员):

class my_string_allocator 
public:
   char * allocate(size_type n, allocator<void>::const_pointer hint=0) 
      // ... grab a chunk from your pre-allocated pool ...
   
;

typedef basic_string<char, char_traits<char>, my_string_allocator> my_string;

class my_vector_allocator 
public:
   my_string * allocate(size_type n, allocator<void>::const_pointer hint=0) 
      // ... similar magic goes here ...
   


vector<my_string, my_vector_allocator> my_string_vector(1000);
for (unsigned int ui=0; ui<1000; ui++)
   my_string_vector[ui].reserve(1024);  // Memory taken from pool; no allocation.

这只有在您确切知道在这些数据结构的生命周期内分配了什么时才真正实用,因为更灵活的分配将需要在分配器中使用类似堆管理的逻辑。

【讨论】:

【参考方案3】:

这将创建一个容量至少为 1024 的单个字符串,然后将其复制构造 1000 次到向量中。

#include <string>
#include <iostream>
#include <vector>

int main() 
   std::string s;
   s.reserve(1024);
   std::vector<std::string> my_string_vector(1000, s);
   std::cout << my_string_vector[42].capacity() << "\n";

【讨论】:

我不确定复制构造函数是否会复制容量。它复制字符串的大小。 我手头没有这个标准,所以我不能肯定地说。但是,Ubuntu 上的 g++ 4.4.3 确实复制了容量。 复制构造函数只保证capacity() &gt;= size()。参见标准第 21.4.2 段,表 64。 我相信g++使用copy-on-write,所以所有的副本实际上都是同一个字符串,直到其中一些被改变。 所以 - 为了清楚起见,这个解决方案是特定于实现的,尽管可以在 g++ 中工作?

以上是关于为字符串向量预分配内存(C++ vector<string>)的主要内容,如果未能解决你的问题,请参考以下文章

C++ 的向量如何分配内存

C++ multimap<int, vector<string>> 内存分配问题

c++ 内存分配向量的指针

C++ 动态分配的 std::vector

预分配的节点向量中的无锁树节点分配

C ++向量内存分配和运行时?