填充指向矢量的指针向量

filling a vector of pointers to vectors

本文关键字:指针 向量 填充      更新时间:2023-10-16

我有一个指向向量的指针向量:

main(...)
{
  //...
  std::vector< std::vector<double> * > ds = getDS(...)
  //...
}
std::vector<std::vector<double> * > getDS(int m, ...)
{
  std::vector<std::vector<double> * > wavefunctions = *(new std::vector<std::vector<double>*>(m));
  int n = int( params.rmax() / params.dr() );
  std::ifstream input_wf;
  input_wf.open(filename.c_str());
  input_wf.setf(std::ios::showpoint | std::ios::scientific);
  for(int i=0; i < nbasis; i++)
  {
    std::vector<double> *wf = new std::vector<double>(n);
    //(wavefunctions[i]) = new std::vector<double>(n);
    for (unsigned int ir=0; ir < wf->size(); ir++)
      input_wf >> ( *wf )[ir];
    wavefunctions.push_back(wf);
  }
  input_wf.close();
  return wave functions;
}

但是,在调试期间,当我尝试访问wavefunctions[0]->at(some legal value)一次循环后,我不断收到EXC_BAD_ACCESS错误。 (那里应该有一些东西,但我不确定为什么没有... 有什么想法吗?

下一行,

  std::vector<std::vector<double> * > wavefunctions = *(new std::vector<std::vector<double>*>(m));

在您的情况下有问题,原因有两个 -

  1. 它会导致内存泄漏,因为new创建的对象被复制到wavefunctions,然后指向它的指针丢失。这不是Java...
  2. 它会在向量中分配m条目。随后的push_back 将添加到该m条目中,因此当您尝试访问wavefunctions[0]时,您实际上访问了在此行中创建的条目,而不是第一个在for循环中推送的条目。

要解决问题,请将行更改为

std::vector<std::vector<double> * > wavefunctions;
wavefunctions.reserve(m);

reserve方法确保您在push_back期间不会有重新分配。

最后要注意的是,根据情况,编译器可能无法优化从函数返回时执行的向量的固有副本。可以肯定的是,您可能希望了解有关 r 值引用 ( &&( 的更多信息,或者只是按地址返回向量(即,作为另一个类型 vector<...> * 的参数并返回类型 void (。

代码看起来应该对我有用,但动态分配太多了。 (尽管您输入了返回值。用户 1071136 发现了错误。

大多数时候,你不应该输入delete,几乎从不输入new。 你也可以在它的构造函数中打开一个流,流会自行关闭,你不必这样做。 您还忘记检查流状态,以查看它是否读取任何值。

std::vector<std::vector<double>> getDS(int m, ...)
{
  std::ifstream input_wf(filename.c_str());
  input_wf.setf(std::ios::showpoint | std::ios::scientific);
  int n = int( params.rmax() / params.dr() );
  std::vector<std::vector<double>> wavefunctions(m, std::vector<double>(n));
  //m by n vector is fully constructed, and ready to read!
  for(int i=0; input_wf && i<nbasis; i++)
  {
    for (unsigned int ir=0; input_wf  && ir<wf->size(); ir++)
      input_wf >> wavefunctions[i][ir];
  }
  if (!input_wf)
      throw std::runtime_error("improper data in the file!");
  return wavefunctions;
}
std::vector<std::vector<double> * > wavefunctions = *(new std::vector<std::vector<double>*>(m));

这在我看来很可疑。我相信你的意思是做两件事之一。

在堆栈上声明它并返回它的副本。

 std::vector<std::vector<double> * > wavefunctions;

在堆上声明它并从函数返回一个指针。(这使调用方负责删除分配的内存。

std::vector<std::vector<double> * > *wavefunctions = new std::vector<std::vector<double>*>(m);

首先,为什么要维护指针向量? 几乎没有充分的理由这样做(我想不出一个,但我并不了解一切。 如果需要存储指针,请存储智能指针。你否定了向量为你管理内存的能力。

std::vector<std::vector<double> * > wavefunctions = *(new std::vector<std::vector<double>*>(m));

在这里,您new一个向量,立即取消引用它并将其复制到本地向量。 那里有一个内存泄漏,因为 new 'd 向量(及其指针(丢失了,你只是简单地复制了它并把它扔掉了。 同样,在向量中存储指针是一个坏主意,并且您的分配方法总是错误的。

只需使用vector<vector<double> >,让向量为您管理动态内存(尽管最好对该主题进行更多研究,以便您了解代码在做什么。

我甚至有点犹豫要不要这么说,但是使用向量模拟锯齿数组时可能会出现性能问题。 问题在于数据的局部性,但这仅适用于性能敏感代码中的紧密循环,并且有许多因素可能会使该点变得毫无意义。