附加到vector<array<char,N>>时如何避免调用memcpy()?

问题描述

下面的代码以 1024 字节的块(块)读取二进制文件,将它们保存到 vector<array<char,1024>> 中,最后打印每个块的第一个字节:

#include <iostream>
#include <fstream>
#include <vector>
#include <array>
#include <iomanip>
#include "string.h"

using namespace std;

int main()
{
   vector<array<char,1024>> blocks;
   vector<char> buffer(1024,0);

   ifstream input("./video.mp4",std::ifstream::binary);

   while( !input.eof() ) {
      input.read( buffer.data(),buffer.size() );
      auto size = input.gcount();

      array<char,1024> aa;
      memcpy( aa.data(),buffer.data(),size );

      blocks.push_back( aa );
   }

   for( auto b: blocks ) {
      cout<<hex<<setw(2)<<setfill('0')<<(int)(uint8_t)b[0]<<'\n';
   }
}

我想避免调用 memcpy,因为这可能不是comme il faut。如何仅使用 C++ std 库完成上述功能?我相信我的编译器最多只支持 C11。

解决方法

  block.emplace_back();
  try {
    input.read( block.back().data(),block.back().size() );
    auto size = input.gcount();
    std::fill_n(block.back().data()+size,block.back().size()-size,'\0' );
  } catch(...) {
    block.resize(block.size()-1);
    throw;
  }

这会用读取数据填充最后一个块,然后将其余块归零。如果抛出异常,则提供强异常保证。

块的内存呈指数增长,给你一个恒定的因子过度分配和一个摊销的线性字节数。如果您知道有多少个区块(或者甚至有一个很好的猜测),您可以提前预订。