我有两个类,一个必须更改另一个类的向量的值。 这是第一个要更改的向量X所在的位置:
Grid.hpp
class Grid{
public:
vector<double> X;
}
另一个类引用了第一个类,并且有一个应该修改X的函数:
BC.hpp
class BC{
public:
Grid &grid;
BC(Grid grid);
~BC(){};
void add_to_X(int n_values);
}
BC.cpp
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;
的main.cpp
int main(){
// grid and bc classes initialized above
bc.add_to_X(10);
}
当我运行上面的main.cpp
时,我收到错误malloc: *** error for object 0x7fb6294027b0: pointer being freed was not allocated
。
我也试过另一个解决方案。我在类grid
中写了一个函数,它将新的向量从类网格本身分配给X
向量,但我仍然有同样的错误。
如果我注释掉行grid.X = new_X;
,则错误消失。
上面的代码有什么问题?什么是正确的编码方式?
答案 0 :(得分:5)
问题在于这一行:
BC::BC(Grid grid): grid(grid){}
这样做,它将传递给构造函数的参数复制到临时grid
中。然后,将成员变量(引用)指定为指向此临时变量。但是,一旦构造函数退出,该临时文件将再次被销毁,因此您的引用将被悬空。
所以你要么必须让它一直向下引用:
BC::BC(Grid& grid): grid(grid){}
然后确保调用者保持相应的Grid
对象处于活动状态,或让BC
存储Grid
的副本而不仅仅是参考。
与suggested in the comments一样,你应该利用这个机会来提高你的调试技巧。崩溃发生时,您的悬空引用将指向无效对象。悬空引用很难自动检测,因此了解调试器中的问题是很有用的。通过在修复调试器之前分析问题,看看是否可以找出出错的地方。