【问题标题】:An effective way to concatenate multiple buffers连接多个缓冲区的有效方法
【发布时间】:2016-04-03 12:25:08
【问题描述】:

我需要设计一个具有两个主要功能的高效可读类:

  • add_buffer(char* buffer) - 添加缓冲区。
  • char* read_all() - 获得一个大缓冲区,其中包含用户到目前为止添加的所有缓冲区(按顺序)。

例如:

char first_buffer[] = {1,2,3};
char second_buffer[] = {4,5,6};

MyClass instance;
instance.add_buffer(first_buffer);
instance.add_buffer(second_buffer);
char* big_buffer = instance.read_all(); // big_buffer = [1,2,3,4,5,6]

注意:这个问题有很多解决方案,但我正在寻找一个有效的解决方案,因为在现实生活中缓冲区会很大很大,我想节省很多复制和重新分配(就像 std::vector 所做的那样)。我也想要一个可读的 C++ 代码。

注意:现实生活中的问题是:我正在从一个 HTTP 请求中读取数据,该请求以分开的块发送给我。在所有块到达后,我想将整个数据返回给用户。

【问题讨论】:

  • 除非您预先分配了大量内存,否则您可能无法避免多次复制重新分配。
  • 是的,我知道。但我想尽量减少它。
  • 输出缓冲区是否需要连续内存?
  • char first_buffer = [1,2,3]; 应该是什么意思?
  • 我正在从一个 HTTP 请求中读取数据,该请求以单独的块发送给我。在所有块到达后,我想将整个数据返回给用户。

标签: c++


【解决方案1】:

使用具有足够内存的std::vector<char> reserved。从 C++11 开始,您可以使用 std::vector::data() 访问内部缓冲区(直到 C++11,您必须使用 &*std::vector::begin())。

【讨论】:

    【解决方案2】:

    如果你可以使用 Boost,boost::algorithm::join 可以:

    #include <boost/algorithm/string/join.hpp>
    #include <vector>
    #include <iostream>
    
    int main(int, char **)
    {
        std::vector<std::string> list;
        list.push_back("Hello");
        list.push_back("World!");
    
        std::string joined = boost::algorithm::join(list, ", ");
        std::cout << joined << std::endl;
    }
    

    输出:

    Hello, World!
    

    Original answer by Tristram Gräbener

    【讨论】:

      【解决方案3】:

      使用一些标准方法,例如,

      • 从一些初始记忆开始,比如 256
      • 只要它得到充分利用,就重新分配并加倍大小。

      如果您不想自己做,请使用 STL 容器,例如

      std::vector<char>
      

      当缓冲区已满时,它会自动为您重新分配内存。

      【讨论】:

      • 这是一个非常糟糕的建议,会导致不可接受和不必要的重新分配。
      • 甚至std::vector也使用相同的策略。如果有人有任何其他策略,请评论。
      猜你喜欢
      • 2021-01-31
      • 2015-03-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多