C++ 填充指向向量的指针向量

C++ 填充指向向量的指针向量,c++,memory,vector,new-operator,C++,Memory,Vector,New Operator,我有一个指向向量的指针向量: main(...) { //... std::vector< std::vector<double> * > ds = getDS(...) //... } std::vector<std::vector<double> * > getDS(int m, ...) { std::vector<std::vector<double> * > wavefunctions = *(n

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

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;
}
main(…)
{
//...
std::vectords=getDS(…)
//...
}
向量getDS(int m,…)
{
std::vector波函数=*(新std::vector(m));
int n=int(params.rmax()/params.dr());
std::ifstream输入\u wf;
输入_wf.open(filename.c_str());
输入_wf.setf(std::ios::showpoint | std::ios::scientific);
for(int i=0;isize();ir++)
输入_wf>>(*wf)[ir];
波函数。推回(wf);
}
输入_wf.close();
返回波函数;
}
但是,在调试过程中,在循环一次之后,当我尝试访问
wavefunctions[0]->at(一些合法值)
时,我总是会遇到EXC\u BAD\u访问错误。(那里应该有一些东西,但我不确定为什么没有……任何想法?

下面一行

  std::vector<std::vector<double> * > wavefunctions = *(new std::vector<std::vector<double>*>(m));
reserve
方法确保在
推回过程中不会重新分配

最后,根据具体情况,编译器可能无法优化从函数返回时执行的向量的固有副本。当然,您可能希望了解有关r值引用(
&&
)的更多信息,或者只需按地址返回向量(即,作为类型为
vector*
和返回类型为
void
)的另一个参数。

std::vector wavefunctions=*(新std::vector(m));
我觉得这很可疑。我相信你的意思是做两件事中的一件

在堆栈上声明并返回其副本

 std::vector<std::vector<double> * > wavefunctions;
std::矢量波函数;
在堆上声明它,并从函数返回指针。(这使调用方负责删除分配的内存。)

std::vector*波函数=新的std::vector(m);
我觉得这段代码应该可以正常工作,但是动态分配太多了。(尽管您键入了返回值。)user1071136发现了错误

大多数情况下,您不应该键入
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::向量getDS(int m,…)
{
std::ifstream input_wf(filename.c_str());
输入_wf.setf(std::ios::showpoint | std::ios::scientific);
int n=int(params.rmax()/params.dr());
std::向量波函数(m,std::向量(n));
//m乘n矢量已完全构建,并准备好读取!
对于(int i=0;输入w f&&i>波函数[i][ir];
}
如果(!input_wf)
抛出std::runtime_错误(“文件中的数据不正确!”);
返回波函数;
}

首先,为什么要维护指针向量?几乎没有很好的理由这样做(我想不出一个,但我不知道一切。)如果你需要存储指针,那么就存储智能指针。你正在否定向量为你管理内存的能力

std::vector<std::vector<double> * > wavefunctions = *(new std::vector<std::vector<double>*>(m));
std::vector波函数=*(新std::vector(m));
在这里,您创建了一个向量,立即取消引用它并将其复制到本地向量。在这里,您出现了内存泄漏,因为
新的
'd向量(及其指针)丢失了,您只需复制它并将其丢弃。同样,在向量中存储指针是一个坏主意,并且您的分配方法总是错误的

只需使用一个
向量
,让该向量为您管理动态内存(不过最好对该主题进行更多的研究,以便您了解您的代码在做什么。)


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

为什么
wavefunctions=*(新的std::vector(m));
而不仅仅是
波函数(m)
?我建议改为使用
std::vector
。这将降低代码的复杂性,并在销毁时适当释放所有内存。typedef可能有助于压缩代码……非常确定返回值与本文中的返回声明不匹配,它不是向量向量,而是点向量ers to vectors…@AndrewSpott:我在看到你的评论之前修复了它,所以,我修复了这个bug(我现在正在堆栈上分配,并进行保留),但是,当创建波函数时,它是在
0xb0
处创建的,后续对它的引用无法读取(在经过一次循环后,尝试读取波函数[0]给出一个
无法访问地址0xb0处的内存的
关键字在适用的情况下\uu;例如,如果函数有多个退出路径,某些版本的Visual Studio将无法NRVO。编译器在这一部分有限制,这将迫使您研究您使用的每个编译器。我想这是r值的原因之一引用。@AndrewSpott:你的代码中有
new
这个词吗?你可能不应该有这个词。@AndrewSpott它对我有用-你必须更具体一些。用你的问题的当前状态编辑你的问题(作为一个单独的部分,以保留原来的部分)。另外,
ds.size()
返回
main
?@AndrewSpott还有,什么是
nbasis
std::vector<std::vector<double> * > *wavefunctions = new std::vector<std::vector<double>*>(m);
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));