【问题标题】:Which data structure is better for an array of std string哪种数据结构更适合 std 字符串数组
【发布时间】:2017-03-15 09:05:33
【问题描述】:

我需要如下结构:

结构必须保持固定大小std::strings,使其元素数为finit (100 - 10000000)。

我希望能够随机访问每个元素,如下所示:

std::string Temp = MyStrcuture[i];

MyStrcuture[i] = std::string Temp;

我必须使用没有(可能)内存泄漏的最快结构。

哪个更适合我?

  1. std::string* MyStrcuture = new std::string[Nu_of_Elements];
  2. std::queue< std:string> MyStrcuture(Nu_of_Elements);
  3. std::vector< std:string> MyStrcuture(Nu_of_Elements);
  4. boost::circular_buffer< std::string> MyStrcuture(Nu_of_Elements);
  5. 您的建议?

【问题讨论】:

  • 队列是否可以随机访问?
  • 另外,C++ 有哈希表吗?可能会很好。
  • unordered_map 接近 C++ 中的哈希表
  • 固定大小std::strings?这是一个不寻常的std::string
  • C++ 中没有 Std:stringStd:vector

标签: c++ string data-structures queue


【解决方案1】:
std::vector< std:string> MyStrcuture(Nu_of_Elements);

Vector 最适合您的要求。它支持基于索引的元素访问,因为元素存储在连续的内存地址中,并且具有大小灵活性。


  1. std:string* MyStrcuture = new std::string[Nu_of_Elements]; 没有

    C++ STL vector vs array in the real world

  2. std::queue MyStrcuture(Nu_of_Elements); 没有

    How do I get the nth item in a queue in java?
    不支持基于索引的元素访问。

  3. std::vector MyStrcuture(Nu_of_Elements); 是的

    Clean-up : 向量的析构函数自动调用向量中每个元素的析构函数。

  4. Boost::circular_buffer<:string> MyStrcuture(Nu_of_Elements); 没有

    与第二个原因相同。 Know more

【讨论】:

  • 从内存的角度来看,std::vector&lt;std::array&lt;char,401&gt;&gt;std::vector&lt;std::string&gt; 更有意义。
  • @themagicalyang:是和否,因为它需要一个巨大的连续内存块,这可能在例如一个碎片化的 32 位地址空间。
  • @MatteoItalia 我同意。但如果是这种情况,则需要对分配进行一些错误检查。但是连续内存仍然是我的首选。如果不回退,则采用不同的分配模式。
【解决方案2】:

好吧,由于您的字符串具有固定大小,如果您在处理字符串时没有专门的要求并且有足够的空闲内存用于连续分配。您可以使用 std::array 或 std::unique_ptr 代替 std::string。

  1. 您必须以 C 方式管理内存。考虑智能指针
  2. std::queue 没有随机访问,Access c++ queue elements like an array

  3. std::vector 适用于要更改字符串数量的情况。但是,clear() 函数只是调用元素的析构函数,而不是释放向量分配的内存(您可以检查清除后的容量)。

  4. 读完boost documentation。如果您的字符串数量有上限(您所说的 1000 万),则随机访问循环缓冲区是合适的。但是,如果实际上您的字符串如此之少,那就浪费了内存。所以我建议使用智能指针。

  5. 如果你的字符串数量是固定的并且从一开始就没有变化。你可以看看C++11 array container

【讨论】:

    【解决方案3】:

    如果元素的数量和长度是固定的并且内存很重要,您可以考虑使用普通的 char 数组,它提供最小的内存开销和快速的可访问性。您的代码将如下所示:

    char* MyStructure = new char[n * 401];
    memset(MyStructure, 0, n * 401);
    
    std::string Temp = MyStructure[i * 401]; // Get value
    strcpy(MyStructure[i * 401], Temp.c_str()); // Put value
    

    这里的 401 代表 400 个字节的字符串和 1 个尾随零。

    【讨论】:

    • 这是正确的解决方案。当字符串大小固定并且可以保存在字符数组中时,为什么要选择动态分配的 std::string 。这样做的更多好处是快速访问,并且没有内存跳跃。虽然我会使用 std::array&lt;char,401&gt; 代替字符串。所以这可能是std::vector&lt;std::array&lt;char,401&gt;
    • 我确定您的意思是 尾随 零。
    • “1 个前导零”?您是说零终止吗?
    • 您没有为字符分配实际内存 - 您只分配了一个指针数组。 strcpy 会出现严重的段错误。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-17
    相关资源
    最近更新 更多