从队列中显示2D数组后程序崩溃

时间:2016-03-25 18:09:20

标签: c++ class multidimensional-array crash

我的C ++程序由一个名为States的类组成,该类必须保存我的拼图的“状态”,即3x3 int数组和另外两个整数。当我在main中声明它们并打印它们时,它们使用正确的值正确打印,但是在将它们放入priority_queue后,按类中的一个int排序,然后将其拉回来,它在数组中有垃圾并且在崩溃时崩溃它试图显示。我不知道为什么当我把它放进去然后拉回来时它会变成垃圾,有人可以解释/帮忙吗?

main.cpp中:

#include "states.h"
#include <cstdlib>
#include <iostream>
#include <queue>

using namespace std;

int main(int argc, char *argv[])
{
priority_queue<States> statesQueue;
int puzzle[3][3];
for(int i=0; i<3; i++)
     for(int j=0; j<3; j++)
         puzzle[i][j] = i+j;

States myPuzzle(puzzle);
States myPuzzle2;

myPuzzle.printPuzzle();
myPuzzle2.printPuzzle();
myPuzzle.setFOfN(5);
myPuzzle2.setFOfN(0);

statesQueue.push(myPuzzle);
statesQueue.push(myPuzzle2);

if(statesQueue.empty()==true)
    cout<< "This is empty" <<endl;
else
    cout<< "This is not empty" <<endl;

statesQueue.top().printPuzzle();

system("PAUSE");
return EXIT_SUCCESS;
}

States.h:

#define STATES_H
#include <iostream>
using namespace std;

class States
{
public:

    States ();
    States (int puzzle[][3]);
    ~States();

    int getFOfN() const;
    void setFOfN(int num);

    int getGOfN() const;
    void setGOfN(int num);

    void incGOfN();
    int** getPuzzle() const;

    void printPuzzle() const;

    bool States::operator<(const States& rhs) const
    {
         return (fOfN < rhs.getFOfN());
    }
    States& operator = (const States& rhs)
    {
        for(int i=0; i<3; i++)
        {
            for(int j=0; j<3; j++)
            {    
                cout<< i << " " << j << " " << rhs.getPuzzle()[i][j] <<endl;
                puzzleGame[i][j] = rhs.getPuzzle()[i][j];
            }
        }
    }                         


private:
    int** puzzleGame;
    int gOfN;
    int fOfN;
};
#endif

States.cpp:。

#include "states.h"
#include <iostream>

States::States ()
{
puzzleGame = new int*[3];

for (int i = 0; i<3; i++)
    puzzleGame[i] = new int[3];

puzzleGame[0][0] = 1;
puzzleGame[0][1] = 2;
puzzleGame[0][2] = 3;
puzzleGame[1][0] = 4;
puzzleGame[1][1] = 0;
puzzleGame[1][2] = 5;
puzzleGame[2][0] = 6;
puzzleGame[2][1] = 7;
puzzleGame[2][2] = 8;

}
//-------------------------------------------------------------------------
States::States (int puzzle[][3])
{
puzzleGame = new int*[3];

for (int i = 0; i<3; i++)
    puzzleGame[i] = new int[3];

for(int i=0; i<3; i++)
    for(int j=0; j<3; j++)
        puzzleGame[i][j] = puzzle[i][j];
}
//-------------------------------------------------------------------------
States::~States()
{
for (int i=0; i<3; i++)
{
    delete [] puzzleGame[i];
}
delete [] puzzleGame;
puzzleGame = 0;
}
//--------------------------------------------------------------------------      
int States::getFOfN() const
{

return fOfN;
}
//-------------------------------------------------------------------------
void States::setFOfN(int num)
{
 fOfN = num;
}
//--------------------------------------------------------------------------      
int States::getGOfN() const
{

return gOfN;
}
//-------------------------------------------------------------------------
void States::setGOfN(int num)
{
 gOfN = num;
}
//--------------------------------------------------------------------------      
void States::incGOfN()
{
 gOfN++;
}
//-------------------------------------------------------------------------
int** States::getPuzzle() const
{

return puzzleGame;
}
//-------------------------------------------------------------------------
void States::printPuzzle() const
{
std::cout<< "+---+---+---+" <<std::endl;
for(int i=0; i<3; i++)
{
    for(int j=0; j<3; j++)
    {
        if(puzzleGame[i][j]==0)
            std::cout<< "|   ";
        else
            std::cout<< "| " << puzzleGame[i][j] << " ";
    }
    std::cout<< "|" <<std::endl;
std::cout<< "+---+---+---+" <<std::endl;
}
}
//-------------------------------------------------------------------------

每次显示时都会发生这种情况: Picture

1 个答案:

答案 0 :(得分:0)

States违反了三条规则,无法安全复制。 What is The Rule of Three?很高兴你问。阅读链接。

在这种情况下,复制States会导致原件和副本指向同一个puzzleGame当一个被删除时,它需要puzzleGame,另一个现在是步行等待调用未定义行为的定时炸弹。

这是一个问题,因为推送到队列会产生一个副本,并且该副本可以被复制,移动,删除或队列的支持容器决定对其进行的任何其他操作。

简单的解决方法是将puzzleGame中的动态States数组替换为静态数组,因为维度已知。 std::array may be helpful here.不太合适的选项包括使用std::vector<std::vector<States>>并实现赋值和移动运算符以及复制和移动正确处理puzzleGame的构造函数。