引发未处理的异常:读取访问冲突。这个->惊奇是0x1110112

时间:2018-12-11 08:16:40

标签: c++ exception exception-handling

我们正在编写一个迷宫解决方案,作为初学者小组项目。

我的队友创建了异常处理部分。

具有讽刺意味的是,使用其异常处理模块运行程序会产生“异常未处理”错误:

  

“引发未处理的异常:读取访问冲突。此-> 迷宫   是0x1110112。发生了

它指向Maze.cpp中的第124行

while (amaze[x][y] != 'F')

我已经本地化了错误的根源: 如果我更改Maze.cpp中的第57行:

if (temp != 'X' && temp != 'F' && temp != ' ')

if(1)

然后它可以正常工作,但是我不明白为什么。有人可以解释吗?

主要

#include <cstdlib>
#include <iostream>
#include "Maze.h"
using namespace std;




int main(int argc, char* argv[])
{
#define OPEN ' '
#define WALL 'X'
#define FINISH 'F'


    cout << "Program START" << endl << endl;


    const int rows1 = 10;
    const int cols1 = 10;
    char maze1[rows1][cols1] = {
        {OPEN, WALL, OPEN, WALL, OPEN, WALL, OPEN, WALL, OPEN, WALL},
        {OPEN, WALL, OPEN, WALL, OPEN, WALL, OPEN, WALL, OPEN, WALL},
        {OPEN, OPEN, OPEN, WALL, OPEN, WALL, OPEN, WALL, OPEN, WALL},
        {OPEN, WALL, OPEN, WALL, OPEN, WALL, OPEN, WALL, OPEN, WALL},
        {OPEN, WALL, OPEN, WALL, OPEN, WALL, OPEN, WALL, OPEN, WALL},
        {OPEN, WALL, OPEN, OPEN, OPEN, WALL, OPEN, WALL, OPEN, FINISH},
        {OPEN, WALL, OPEN, WALL, OPEN, WALL, OPEN, OPEN, OPEN, WALL},
        {OPEN, WALL, OPEN, WALL, OPEN, WALL, OPEN, WALL, OPEN, WALL},
        {OPEN, WALL, OPEN, WALL, OPEN, OPEN, OPEN, WALL, OPEN, WALL},
        {OPEN, WALL, OPEN, WALL, OPEN, WALL, OPEN, WALL, OPEN, WALL}
    };


    //////////////////////////////////////////////////////////////////////////////

    // Very clumsy way to allow for variable rows and columns, for now.
    char *b1[cols1];
    for (int r = 0; r < rows1; r++)
        b1[r] = maze1[r];


    maze1[4][5] = 'C';
    char *b4 = nullptr;


    Maze game;

    try {
        game.set_maze(b1, rows1, cols1);
    }
    catch (const char *msg)
    {
        cout << "Error: " << msg << endl;
    }

    try {
        game.set_maze(NULL, rows1, cols1);
    }
    catch (const char *msg)
    {
        cout << "Error: " << msg << endl;
    }
    try {
        game.set_maze(&b4, rows1, cols1);
    }
    catch (const char *msg)
    {
        cout << "Error: " << msg << endl;
    }

    try {
        game.set_maze(b1, -1, 10);
    }
    catch (const char *msg)
    {
        cout << "Error: " << msg << endl;
    }

    try {
        game.set_maze(b1, rows1, -10);
    }
    catch (const char *msg)
    {
        cout << "Error: " << msg << endl;
    }

    game.print();                    // Make sure its right.

    bool solved = game.solve_with_vector();
    if (solved == true) cout << "YEAH! solved with vector!\n";
    else cout << "BOO! can't solve with vector!\n";
    game.print();


    //////////////////////////////////////////////////////////////////////////////

      // Another solvable maze alternative to the starter version
    const int rows2 = 16;
    const int cols2 = 20;
    char maze2[rows2][cols2] = {
        {OPEN, OPEN, OPEN, OPEN, OPEN, OPEN, OPEN, OPEN, OPEN, OPEN, OPEN, OPEN, OPEN, OPEN, OPEN, OPEN, OPEN, OPEN, OPEN, OPEN},
        {OPEN, WALL, WALL, WALL, WALL, OPEN, WALL, WALL, WALL, WALL, WALL, WALL, WALL, WALL, OPEN, WALL, WALL, WALL, WALL, OPEN},
        {OPEN, WALL, OPEN, OPEN, OPEN, OPEN, OPEN, OPEN, OPEN, OPEN, OPEN, OPEN, OPEN, OPEN, OPEN, OPEN, OPEN, OPEN, WALL, OPEN},
        {OPEN, WALL, OPEN, WALL, WALL, WALL, WALL, WALL, WALL, WALL, WALL, WALL, WALL, WALL, WALL, WALL, WALL, OPEN, WALL, OPEN},
        {OPEN, WALL, OPEN, WALL, OPEN, OPEN, OPEN, OPEN, OPEN, OPEN, OPEN, OPEN, OPEN, OPEN, OPEN, OPEN, WALL, OPEN, WALL, OPEN},
        {OPEN, WALL, OPEN, WALL, OPEN, WALL, WALL, WALL, WALL, WALL, OPEN, WALL, WALL, WALL, WALL, OPEN, WALL, OPEN, WALL, OPEN},
        {OPEN, OPEN, OPEN, WALL, OPEN, WALL, OPEN, OPEN, OPEN, OPEN, OPEN, OPEN, OPEN, OPEN, WALL, OPEN, WALL, OPEN, WALL, OPEN},
        {OPEN, WALL, OPEN, WALL, OPEN, OPEN, OPEN, WALL, WALL, FINISH, WALL, WALL, OPEN, OPEN, WALL, OPEN, WALL, OPEN, WALL, OPEN},
        {OPEN, WALL, OPEN, WALL, OPEN, WALL, OPEN, WALL, WALL, WALL, WALL, WALL, OPEN, OPEN, WALL, OPEN, WALL, OPEN, OPEN, OPEN},
        {OPEN, WALL, OPEN, WALL, OPEN, WALL, OPEN, OPEN, OPEN, OPEN, OPEN, OPEN, OPEN, OPEN, WALL, OPEN, WALL, OPEN, WALL, OPEN},
        {OPEN, WALL, OPEN, WALL, OPEN, WALL, WALL, WALL, OPEN, WALL, WALL, WALL, WALL, WALL, WALL, OPEN, WALL, OPEN, WALL, OPEN},
        {OPEN, WALL, WALL, WALL, OPEN, OPEN, OPEN, OPEN, OPEN, OPEN, OPEN, OPEN, OPEN, OPEN, OPEN, OPEN, OPEN, OPEN, WALL, OPEN},
        {OPEN, WALL, OPEN, WALL, WALL, OPEN, WALL, WALL, WALL, WALL, WALL, WALL, WALL, WALL, WALL, WALL, WALL, OPEN, WALL, OPEN},
        {OPEN, WALL, OPEN, OPEN, OPEN, OPEN, OPEN, OPEN, OPEN, OPEN, OPEN, OPEN, OPEN, OPEN, OPEN, OPEN, OPEN, OPEN, WALL, OPEN},
        {OPEN, WALL, WALL, WALL, WALL, WALL, WALL, WALL, WALL, OPEN, WALL, WALL, WALL, WALL, WALL, WALL, WALL, WALL, WALL, OPEN},
        {OPEN, OPEN, OPEN, OPEN, OPEN, OPEN, OPEN, OPEN, OPEN, OPEN, OPEN, OPEN, OPEN, OPEN, OPEN, OPEN, OPEN, OPEN, OPEN, OPEN}

    };

    //////////////////////////////////////////////////////////////////////////////

      // Very clumsy way to allow for variable rows and columns, for now.
    char *b2[cols2];
    for (int r = 0; r < rows2; r++)
        b2[r] = maze2[r];

    Maze game2;    // Do another solvable different size

    game2.set_maze(b2, rows2, cols2);

    game2.print();

    solved = game2.solve_with_vector();
    if (solved == true) cout << "YEAH! solved with vector!\n";
    else cout << "BOO! can't solve with vector!\n";

    game2.print();

    //////////////////////////////////////////////////////////////////////////////

   // This maze does not contain a finish so is unsolveable.
   // Use to test whether you are actually traversing the whole maze.
   // Output should be the maze with all open spaces changed to . (dots)

    const int rows3 = 10;
    const int cols3 = 10;
    char maze3[rows3][cols3] = {
        {OPEN, WALL, OPEN, WALL, OPEN, WALL, OPEN, WALL, OPEN, WALL},
        {OPEN, WALL, OPEN, WALL, OPEN, WALL, OPEN, WALL, OPEN, WALL},
        {OPEN, OPEN, OPEN, WALL, OPEN, WALL, OPEN, WALL, OPEN, WALL},
        {OPEN, WALL, OPEN, WALL, OPEN, WALL, OPEN, WALL, OPEN, WALL},
        {OPEN, WALL, OPEN, WALL, OPEN, WALL, OPEN, WALL, OPEN, WALL},
        {OPEN, WALL, OPEN, OPEN, OPEN, WALL, OPEN, WALL, OPEN, WALL},
        {OPEN, WALL, OPEN, WALL, OPEN, WALL, OPEN, OPEN, OPEN, WALL},
        {OPEN, WALL, OPEN, WALL, OPEN, WALL, OPEN, WALL, OPEN, WALL},
        {OPEN, WALL, OPEN, WALL, OPEN, OPEN, OPEN, WALL, OPEN, WALL},
        {OPEN, WALL, OPEN, WALL, OPEN, WALL, OPEN, WALL, OPEN, WALL}
    };

    //////////////////////////////////////////////////////////////////////////////

      // Very clumsy way to allow for variable rows and columns, for now.
    char *b3[cols3];
    for (int r = 0; r < rows3; r++)
        b3[r] = maze3[r];

    Maze game3;    // Do an unsolvable

    game3.set_maze(b3, rows3, cols3);

    game3.print();

    solved = game3.solve_with_vector();
    if (solved == true) cout << "YEAH! solved with vector!\n";
    else cout << "BOO! can't solve with vector!\n";

    game3.print();


    return 0;
}

Maze.cpp

#include <iostream>
#include <vector>
#include "Maze.h"

using namespace std;

// Constructor only initializes class variables.
Maze::Maze() {
    rows = cols = 0;
    amaze = NULL;
}

// Destructor doesn't have anything to do but is left as a place holder
//      for any future features that need cleanup.
Maze::~Maze() {
    // Nothing to get rid of since we just point to the users supplied maze.
}

// Attach a users maze.  Keep track of number of rows and columns in it.
void Maze::set_maze(char ** maz, int numr, int numc) {



    if (maz == nullptr)
    {
        throw "maz nullptr";
    }

    if (*maz == nullptr)
    {
        throw "*maz nullptr";
    }
    if (numr <= 0)
    {
        throw "rows must be positive value";
    }

    if (numc <= 0)
    {
        throw "columns must be positive value";
    }

    char temp = NULL;
    for (int j = 0; j < numr; j++)
    {
        for (int k = 0; k < numc; k++)
        {
            temp = maz[j][k];       // Using a temp variable for code readability
            if (temp != 'X' && temp != 'F' && temp != ' ')
            {
                //cout << "ivalid maze element (character) at [r],[c]: [" << j << "],[" << k << "]\n";
                throw "ivalid maze element (character)";
            }
        }
    }

    rows = numr;
    cols = numc;
    amaze = maz;

}

// Determine if a row and column are inside the maze and 
//      not a wall nor already searched.
//
// Returns:
//      true for open inside not searched.
//      false if its outside, wall, already searched or finish.
//
bool Maze::check_if_open(int r, int c) {
    // Any row or column that is negative is outside.
    // Any row or column that is greater than the values passed to set_maze are outside.
    if (r < 0 || c < 0 || r >= rows || c >= cols) {    // Outside
        return false;
    }
    // '.' is already searched, 'F' is the finish, 'S' is the start, 'X' is wall
    // We only check for this so we can be sure that when we get to the end we have
    // checked all valid possibilities.



    if (amaze[r][c] == '.' || amaze[r][c] == 'X' || amaze[r][c] == 'S') { // not open
        return false;
    }


    if (amaze[r][c] == ' ' || amaze[r][c] == 'F') { // open
        return true;
    }
    // If we get here it is something unexpected so its an error.
    cout << "Error: Unexpected state found in maze: " << amaze[r][c] << endl;
    return false;
}

// YOUR COMMENTS GO HERE
bool Maze::solve_with_vector() {




    class Alt                   // Nested Class for alternative route's coordinates
    {
    public:int x; int y;
    };

    vector<Alt> alt;


    // Current position:
    int x = 0;  // current raw - Starting at (0,0) according to handout
    int y = 0;  // current column - Starting at (0,0) according to handout

    alt.clear();    // Clear our vector of alternative paths


    while (amaze[x][y] != 'F')  // Loop until found Finish or ran out of alternative paths
    {


        amaze[x][y] = '.';      // Set current location to visited


        if (check_if_open(x - 1, y) == true)        // if neighbor up (amaze[row-1][col]) is open, push it
        {
            alt.push_back(Alt());
            alt.back().x = x - 1;
            alt.back().y = y;
        }


        if (check_if_open(x, y + 1) == true)        // if neighbor right (amaze[row][col+1]) is open, push it
        {
            alt.push_back(Alt());
            alt.back().x = x;
            alt.back().y = y + 1;
        }



        if (check_if_open(x + 1, y) == true)        // if neighbor down (amaze[row+1][col]) is open, push it
        {
            alt.push_back(Alt());
            alt.back().x = x + 1;
            alt.back().y = y;
        }


        if (check_if_open(x, y - 1) == true)        // if neighbor left (amaze[row][col-1]) is open, push it
        {
            alt.push_back(Alt());
            alt.back().x = x;
            alt.back().y = y - 1;
        }


        if (alt.empty())                            // if vector is empty, maze is unsolvable, so return false 
        {
            return false;
        }                                           // else pop a path from the vector  (i.e. reset current row and column from vector)
        else
        {
            x = alt.back().x;
            y = alt.back().y;
            alt.pop_back();
        }
    }

    return true;    // If found "Finish", return true


}



// Print the current state of the maze.
// Maze if made up of chars where:
//              ' ' is open, 
//              'X' is wall, 
//              'F' is finish, 
//              '.' is already searched
//
void Maze::print() {
    for (int row = 0; row < rows; row++) {
        for (int col = 0; col < cols; col++) {
            cout << amaze[row][col] << " ";
        }
        cout << endl;
    }
    cout << endl;
}

Maze.h

#ifndef MAZE_H
#define MAZE_H

#include <iostream>
#include <vector>

using namespace std;

class Maze {
private:
    char ** amaze;            // The maze
    int rows;                 // Number of rows in the maze
    int cols;                 // Number of cols in the maze
    bool check_if_open(int row, int col);
    // Check if open (not wall, not outside, not already searched, not a finish ...)
    bool finished(int row, int col);


public:
    Maze();                   // constructor
    ~Maze();                  // destructor
    void set_maze(char ** maz, int numr, int numc);
    bool solve_with_vector(); // solves maze, alternate possible routes are saved in a vector        
    void print();            // prints current state of maze,
    // ' ' is open, 'X' is wall, 'F' is finish, '.' is searched
};
#endif /* MAZE_H */

0 个答案:

没有答案