C++ 修改其他类的向量成员时出错

C++ 修改其他类的向量成员时出错,c++,vector,C++,Vector,我有两个类,一个必须改变另一个类的向量值。 这是第一个,其中要更改的向量X位于: Grid.hpp class Grid{ public: vector<double> X; } class BC{ public: Grid &grid; BC(Grid grid); ~BC(){}; void add_to_X(int n_values); } BC::BC(Grid grid): grid(grid){} void BC::add

我有两个类,一个必须改变另一个类的向量值。 这是第一个,其中要更改的向量X位于:

Grid.hpp

class Grid{
  public:
    vector<double> X;
}
class BC{

  public:

  Grid &grid;
  BC(Grid grid);
  ~BC(){};
  void add_to_X(int n_values);
}
BC::BC(Grid grid): grid(grid){}

void BC::add_to_X(int n_values){
  vector<double> new_X;
  for(int i=0; i<n_values; i++){
    new_X.push_back(0.1);
  }
  grid.X = new_X;
int main(){
// grid and bc classes initialized above
bc.add_to_X(10);
}
BC.cpp

class Grid{
  public:
    vector<double> X;
}
class BC{

  public:

  Grid &grid;
  BC(Grid grid);
  ~BC(){};
  void add_to_X(int n_values);
}
BC::BC(Grid grid): grid(grid){}

void BC::add_to_X(int n_values){
  vector<double> new_X;
  for(int i=0; i<n_values; i++){
    new_X.push_back(0.1);
  }
  grid.X = new_X;
int main(){
// grid and bc classes initialized above
bc.add_to_X(10);
}
当我运行上面的
main.cpp
时,我得到错误
malloc:**对象0x7fb6294027b0的错误:未分配要释放的指针
。 我还尝试了另一种解决方案。我在类
网格
中编写了一个函数,该函数从类网格本身将新向量分配给
X
向量,但仍然存在相同的错误。 如果我注释掉行
grid.X=new\ux错误消失。

上面的代码有什么问题?正确的编码方式是什么?

问题是这行:

BC::BC(Grid grid): grid(grid){}
这样做的目的是,它将传递给构造函数的参数复制到临时
网格中。然后为成员变量指定一个引用,以指向该临时变量。然而,一旦构造器退出,该临时文件将再次被销毁,因此您的引用将悬而未决

因此,您必须使其始终处于引用状态:

BC::BC(Grid& grid): grid(grid){}
然后确保调用者保持相应的
网格
对象处于活动状态,或者让
BC
存储
网格
的副本,而不仅仅是引用


正如以前一样,您应该利用这个机会来提高调试技能。当崩溃发生时,您的悬挂引用将指向无效对象。悬空引用很难自动检测,因此了解调试器中的此类问题是很有用的。在修复问题之前,请先在调试器中分析问题,看看是否可以找出问题所在。

问题是这一行:

BC::BC(Grid grid): grid(grid){}
这样做的目的是,它将传递给构造函数的参数复制到临时
网格中。然后为成员变量指定一个引用,以指向该临时变量。然而,一旦构造器退出,该临时文件将再次被销毁,因此您的引用将悬而未决

因此,您必须使其始终处于引用状态:

BC::BC(Grid& grid): grid(grid){}
然后确保调用者保持相应的
网格
对象处于活动状态,或者让
BC
存储
网格
的副本,而不仅仅是引用


正如以前一样,您应该利用这个机会来提高调试技能。当崩溃发生时,您的悬挂引用将指向无效对象。悬空引用很难自动检测,因此了解调试器中的此类问题是很有用的。在修复问题之前,请先在调试器中分析问题,看看是否可以找出问题所在。

欢迎使用堆栈溢出!听起来您可能需要学习如何使用a来逐步完成代码。有了一个好的调试器,您可以逐行执行您的程序,并查看它偏离预期的地方。这是一个必要的工具,如果你要做任何编程。进一步阅读:。我使用调试器编辑了文章。该行为网格。X=新的_X;这导致了问题。我暂时建议
Grid&Grid
没有达到您希望它达到的目的,因此除了ComicSansMs的解释(如下),您可能想问问自己为什么要使用引用,而不是简单地按值保存
网格。这不是Java,引用也不一样。如果是为了避免重复或将所有权保留在
BC
之外,那么智能指针或共享指针可能是更好的选择。欢迎使用堆栈溢出!听起来您可能需要学习如何使用a来逐步完成代码。有了一个好的调试器,您可以逐行执行您的程序,并查看它偏离预期的地方。这是一个必要的工具,如果你要做任何编程。进一步阅读:。我使用调试器编辑了文章。该行为网格。X=新的_X;这导致了问题。我暂时建议
Grid&Grid
没有达到您希望它达到的目的,因此除了ComicSansMs的解释(如下),您可能想问问自己为什么要使用引用,而不是简单地按值保存
网格。这不是Java,引用也不一样。如果是为了避免重复或将所有权保留在BC之外,那么智能指针或共享指针可能是更好的选择。谢谢!这就解决了问题!从现在起,我将使用调试器。你对此有什么建议吗?@MattiaCipriani任何适合你的工具链的东西:大多数IDE(visualstudio、CLion、XCode等)都有集成调试支持,这应该是你使用IDE时的第一选择。除此之外,还有用于gcc的gdb和用于clang的lldb,它们都非常强大,但比ide中的图形调试器具有更陡峭的学习曲线。在Windows上还有WinDbg,它也是非常强大的,但是如果你只想调试简单的应用程序,那可能就太过分了。谢谢!这就解决了问题!从现在起,我将使用调试器。你对此有什么建议吗?@MattiaCipriani任何适合你的工具链的东西:大多数IDE(visualstudio、CLion、XCode等)都有集成调试支持,这应该是你使用IDE时的第一选择。除此之外,还有用于gcc的gdb和用于clang的lldb,它们都非常强大,但比ide中的图形调试器具有更陡峭的学习曲线。在Windows上也有WinDbg,它也非常强大,但如果您只想调试简单的应用程序,那么它可能会有些过头。