按值传递对象时出现断言错误--它是我的复制构造函数
Assertion error when passing object by value -- it is my copy constructor?
大家好!
我刚写完一个使用动态内存分配的2-D迷宫(Class是一个名为"迷宫"的ADT——多么新颖(。我将迷宫传递给另一个类的方法,我称之为"迷宫求解器",它使用递归和回溯来求解迷宫。好消息是,当我通过引用传递对象时,我的代码编译得非常好。我不知道是好是坏的消息是,如果我试图按值将迷宫传递给迷宫求解器,就会出现断言错误。
假设只有当我传递值时才会发生错误,我只能假设它与我的复制构造函数有关。在继续之前,这里有一些关于代码的信息:
迷宫是由正方形组成的。每个正方形都由一个名为SquareData的结构表示。
struct SquareData
{
//data fields for the struct (NO POINTERS)
}
我决定用SquareData指针的向量来表示整个迷宫(这个向量在类"迷宫"的私有部分(。
vector<SquareData*> squares;
我的析构函数的实现是这样的(引用Player类的最后一个调用只是消除了一个悬挂指针,我已经声明它是该类的静态变量,我已经指向了迷宫。我认为考虑这个问题并不重要,但我毕竟是C++的新手,你们中的一个人可能会认为它可能是,所以我在"hmmms"中包含了它(:
// clears maze of its contents
void Maze::clear() {
int totalSquares = squares.size();
for (int loopVar = 0; loopVar < totalSquares; loopVar++)
{
delete squares[loopVar]; // deallocate memory by deleting the square structure
squares[loopVar] = nullptr; // eliminate dangling pointer
} // vector takes care of itself
} // end clear
Maze::~Maze(){
//clear the maze of contents (vector is full of pointers whose memory is on the heap)
clear();
//vector safe to deallocate itself now
Player::setMaze(nullptr); // remove the pointer from player
}
我已经在头中声明了复制构造函数如下:
/** Copy Constructor */
Maze(const Maze& myMaze);
尝试实现:
/** copy constructor */
Maze::Maze(const Maze& myMaze){
/** Initialize Constants */
mazeLength = myMaze.mazeLength;
mazeWidth = myMaze.mazeWidth;
exitRow = myMaze.exitRow;
exitCol = myMaze.exitCol;
entRow = myMaze.entRow;
entCol = myMaze.entCol;
/** copy the vector of pointers*/
for (int loopVar = 0; loopVar < myMaze.squares.size(); loopVar++)
{
squares.push_back(myMaze.squares[loopVar]);
}
} // end copy constructor
以下是我试图了解问题的原因:
我在中为我的Maze类编写了这个矢量显示函数。
void Maze::vectorDisplay() const {
for (int loopVar = 0; loopVar < squares.size(); loopVar++)
{
cout << "Vector Index: " << loopVar << endl;
cout << "Pointer: " << squares[loopVar] << endl;
cout << "Row: " << squares[loopVar]->Row << endl;
cout << "Col: " << squares[loopVar]->Col << endl;
cout << "State: " << squares[loopVar]->State << endl;
}
} //end vectorDisplay
并发现在驱动器中执行以下操作时矢量显示正确:
Maze myMazeObject(// parameters);
myMazeObject.vectorDisplay();
并且将毫无怨言地产生输出。
但现在,如果我在传递值时尝试使用这样的代码:
Maze myMazeObject(// parameters);
MazeSolver myMazeSolver;
myMazeSolver.someMazeSolverMethod(myMazeObject);
在someMazeSolverMethod具有行myMazeObject.vectorDisplay();
的情况下,我在打印矢量中的最后一个元素时得到断言错误。
我想说这是我的错,我的副本构造函数是一个p.o.s。如果有任何见解,请让我知道如何修复它,以及我将来能做什么!
感谢你花时间阅读,如果你愿意的话,更感谢你的回答!
-J
这是您的问题。
squares.push_back(myMaze.squares[loopVar]);
基本上,每个迷宫都有一个充满相同指针的向量。当迷宫的一个副本超出范围时,它将删除所有指针。因此,另一个迷宫现在有一组无效的指针。
几个解决方案。
- 不要使用指针
除非SquareData
是多态的,否则似乎没有理由保留指针。
std::vector<SquareData> squares;
- 如果你想让迷宫的每个副本都指向相同的正方形
然后使用共享指针。这将保持对每个SquareData
的引用数量的计数,因此只有当它们真正超出范围时才会删除它们。
std::vector<std::shared_ptr<SquareData>> squares;
- 最不吸引人(可能不需要(
更改代码以将指针内容实际复制到新对象中。
squares.push_back(new SquareData(myMaze.squares[loopVar]));
的使用
squares.push_back(myMaze.squares[loopVar]);
在复制构造函数中将导致下游出现问题。如果squares
的内容是对象而不是指针,那么这将是有效的。
现在有两个对象在指针上。两者都会尝试在同一指针上调用delete
,这很容易导致未定义的行为。
您可以通过以下方式解决问题:
- 使用
vector
对象而不是指针的vector
,或者 从堆中创建新对象并将它们添加到新对象中。
squares.push_back(new SquareData(*myMaze.squares[loopVar]));
- 模板,函数使用错误的构造函数来复制我的对象
- 为什么当我尝试返回引用时,我的对象仍然被复制
- 为什么我的运算符 + 重载尽管是通过引用传递的,但仍调用我的复制构造函数?
- 为什么当我做复制和交换习语时不调用我的复制构造函数?
- 为什么我的复制构造函数被删除
- 我需要做一个深度复制,我是否正确使用了我的复制构造函数?
- 假设我有作业运算符,我的复制构造函数是this = obj可以
- 为什么我的复制构造函数出现"undefined reference to"错误?
- 为什么我的复制构造函数没有被调用
- 为什么我不能在我的复制构造函数中使用 std::copy?
- 我的复制构造函数导致使用我的类的方法失败.有人能看一眼,告诉我我做错了什么吗
- 为什么我的复制构造函数不适用于新调用并且具有相同的内存地址
- 我的复制构造函数有什么问题?
- 为什么我的复制构造函数不起作用?
- 我的复制构造函数出了什么问题
- 为什么在这种情况下我的复制构造函数只被调用两次?
- 为什么我的复制列表初始化停止工作后,我添加继承
- 我的复制构造函数是错误的.它们应该是什么样子?
- 为什么每次我试图改变对象时,我的复制构造函数都会产生段错误?
- 按值传递对象时出现断言错误--它是我的复制构造函数