【问题标题】:c++ write vectors to hdf5-file without storing in arrayc ++将向量写入hdf5文件而不存储在数组中
【发布时间】:2021-03-27 03:21:48
【问题描述】:

我正在尝试将 4 个向量(大小可变,但所有 4 个具有相同大小)存储在 .h5 文件中。 直到现在,我都是这样做的:

void write_file_h5(std::string filename,
            std::vector<int16_t> &x,
            std::vector<int16_t> &y,
            std::vector<int8_t> &p,
            std::vector<int32_t> &ts)
{
  struct myEvent myEvents[x.size()];
  for (int i=0; i<x.size();i++)
  {
    myEvents[i].x = x[i];
    myEvents[i].y = y[i];
    myEvents[i].p = int(p[i]);
    myEvents[i].ts = ts[i];
  }
  H5::CompType mtype(sizeof(myEvent));
  // Define the datatype to pass HDF5
  mtype.insertMember("x", HOFFSET(myEvent, x), H5::PredType::NATIVE_INT16);
  mtype.insertMember("y", HOFFSET(myEvent, y), H5::PredType::NATIVE_INT16);
  mtype.insertMember("p", HOFFSET(myEvent, p), H5::PredType::NATIVE_INT8);
  mtype.insertMember("ts", HOFFSET(myEvent, ts), H5::PredType::NATIVE_INT32);


  // preparation of a dataset and a file.
  hsize_t dim[1];
  dim[0] = sizeof(myEvents) / sizeof(myEvent);
  int rank = sizeof(dim) / sizeof(hsize_t);
  H5::DataSpace space(rank, dim);
  H5::H5File *file = new H5::H5File(filename, H5F_ACC_TRUNC);
  H5::DataSet *dataset = new H5::DataSet(file->createDataSet("myDataset", mtype, space));
  dataset->write(myEvents, mtype);
  delete dataset;
  delete file;
}

这样做的问题是:随着向量变大(向量大小 > 732428),出现分段错误:

Segmentation fault (core dumped)

我认为这是因为我尝试创建的数组太大了。 有谁知道如何解决这个问题?即如何在使用最少内存的同时编写向量? 我需要向量,因为我需要在程序执行期间动态填充它们......所以直接将值存储在数组中似乎是不可能的。

提前致谢

【问题讨论】:

  • 查找迭代器:for (auto xit = x.begin (); xit != x.end (); xit++) do_something_with (*xit);
  • 您不能仅仅因为通过堆分配的内存限制而获得分段错误(如果以正确的方式完成)。但是在您的示例中,您应用了应该避免的堆栈分配。
  • struct myEvent myEvents[x.size()]; - 这是一个 VLA(非标准)。请改用std::vector&lt;myEvent&gt; myEvents(x.size());。您是否还检查过所有传入向量的大小是否相同?
  • H5类中使用newdelete吗?而不是H5::H5File *file = new H5::H5File(filename, H5F_ACC_TRUNC);(然后是delete file)使用H5::H5File file(filename, H5F_ACC_TRUNC);而不是delete会更干净。
  • @TedLyngmo 感谢您的回答。分段错误确实发生在“struct MyEvent myEvents[x.size()];”线...所以这一定是个问题。但是,它必须是结构而不是向量,因为 H5 类不接受向量。另外,我检查了所有传入的向量是否具有相同的大小...您对如何修复结构有想法吗?

标签: c++ vector hdf5


【解决方案1】:

这一行

struct myEvent myEvents[x.size()];

创建一个variable-length array,它是一个可能放置在堆栈上的非标准(C++ 中)数组。

将其替换为 std::vector&lt;myEvent&gt; 以在堆上分配内存。

void write_file_h5(std::string filename,
            std::vector<int16_t> &x,
            std::vector<int16_t> &y,
            std::vector<int8_t> &p,
            std::vector<int32_t> &ts)
{
  // Suggestion: check that y, p and ts has at least as many elements as x
  std::vector<myEvent> myEvents(x.size());  // replacement for the VLA

  for (int i=0; i<x.size();i++) {
    myEvents[i].x = x[i];
    myEvents[i].y = y[i];
    myEvents[i].p = int(p[i]);
    myEvents[i].ts = ts[i];
  }

  H5::CompType mtype(sizeof(myEvent));
  // Define the datatype to pass HDF5
  mtype.insertMember("x", HOFFSET(myEvent, x), H5::PredType::NATIVE_INT16);
  mtype.insertMember("y", HOFFSET(myEvent, y), H5::PredType::NATIVE_INT16);
  mtype.insertMember("p", HOFFSET(myEvent, p), H5::PredType::NATIVE_INT8);
  mtype.insertMember("ts", HOFFSET(myEvent, ts), H5::PredType::NATIVE_INT32);

  // preparation of a dataset and a file.
  hsize_t dim[1];
  dim[0] = myEvents.size();                   // using vector::size()
  int rank = sizeof(dim) / sizeof(hsize_t);
  H5::DataSpace space(rank, dim);

  H5::H5File *file = new H5::H5File(filename, H5F_ACC_TRUNC);
  H5::DataSet *dataset = new H5::DataSet(file->createDataSet("myDataset", mtype, space));
  dataset->write(myEvents.data(), mtype);     // use vector::data()
  delete dataset;
  delete file;
}

我还建议不要使用newdelete 来简化函数的最后一部分:

  H5::H5File file(filename, H5F_ACC_TRUNC);
  H5::DataSet dataset(file.createDataSet("myDataset", mtype, space));
  dataset.write(myEvents.data(), mtype);

【讨论】:

    猜你喜欢
    • 2016-03-22
    • 1970-01-01
    • 2015-06-03
    • 1970-01-01
    • 2020-12-17
    • 2017-05-20
    • 2022-01-14
    • 2013-05-14
    • 2015-07-27
    相关资源
    最近更新 更多