C++ 修改其他类的向量成员时出错
我有两个类,一个必须改变另一个类的向量值。 这是第一个,其中要更改的向量X位于: Grid.hppC++ 修改其他类的向量成员时出错,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
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,它也非常强大,但如果您只想调试简单的应用程序,那么它可能会有些过头。