迷宫生成矢量分割故障

时间:2018-02-25 05:13:30

标签: c++ vector

代码使用深度优先搜索算法创建迷宫。代码编译完全正常,但在运行时会产生分段错误。 这是代码:

#include "stdafx.h"
#include <cctype>
#include <ctime>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <vector>
#include "maze2.h"

enum mDirection { UP = 0, DOWN = 1, LEFT = 2, RIGHT = 3 };

//the alrogrithm used for maze generation is the depth first search algorithm 
//i followed this as a guide http://www.migapro.com/depth-first-search/
//the link uses arrays but i've tried to use vectors as i believe using arrays was one cause of an issue in the last maze generation code


bool Maze::randDirection(bool firstMove) {
    int randAdjSquare;
    std::vector<std::vector<int>> unvisAdjSquare; //unvisited adjacent squares

    for (int direction = 0; direction < 4; direction++) { //i is the direction
        int possible_pmd[2] = { 0, 0 };

        if (direction == UP) {
            possible_pmd[1] = -1;
        }
        else if (direction == DOWN) {
            possible_pmd[1] = 1;
        }
        else if (direction == LEFT) {
            possible_pmd[0] = -1;
        }
        else {
            possible_pmd[0] = 1;
        }

        if (algoPath.back()[0] + possible_pmd[0] * 2 >0 && algoPath.back()[0] + possible_pmd[0] * 2 <mazeSize[0] - 1 && algoPath.back()[1] + possible_pmd[1] * 2 > 0 && algoPath.back()[1] + possible_pmd[1] * 2 < mazeSize[1] - 1) {
            if (!maze[algoPath.back()[1] + possible_pmd[1] * 2]
                [algoPath.back()[0] + possible_pmd[0] * 2][1]) {
                std::vector<int> possMove = { possible_pmd[0], possible_pmd[1] };
                unvisAdjSquare.push_back(possMove);
            }
        }

        if (unvisAdjSquare.size() > 0) {
            randAdjSquare = rand() % unvisAdjSquare.size();

            for (int i = 0; i< !firstMove + 1; i++) {
                std::vector<int> nextPlace;

                nextPlace.push_back(algoPath.back()[0] + unvisAdjSquare[randAdjSquare][0]);
                nextPlace.push_back(algoPath.back()[1] + unvisAdjSquare[randAdjSquare][1]);
                algoPath.push_back(nextPlace);

                maze[algoPath.back()[1]][algoPath.back()[0]][0] = false;
                maze[algoPath.back()[1]][algoPath.back()[0]][1] = true;
            }
            return true;
        }
        else {
            return false;
        }
    }
    return true;
}

void Maze::generateMaze() {
    bool firstMove = true;
    bool worked = true;
    while ((int)algoPath.size() > 1 - firstMove) {
        if (!worked) {
            algoPath.pop_back();
            if (!firstMove && algoPath.size() > 2) {
                algoPath.pop_back();
            }
            else {
                break;
            }
            worked = true;
        }
        while (worked) {
            worked = randDirection(firstMove);

            if (firstMove) {
                firstMove = false;
            }
        }
    }
}

void Maze::initMaze() { //this function sets up the vector as a grid of the size defined before in the mazeSize variable
    for (int i = 0; i < mazeSize[1]; i++) {
        for (int j = 0; j <mazeSize[0]; j++) {
            bool isEdge; // this bool checks to see if the next square is the edge of the vector, if it is, keep going back until the algorithm is able to move in a new direction

            if (i == 0 || i == mazeSize[1] - 1 || j == 0 || j == mazeSize[0] - 1) {
                isEdge = true;
            }
            else {
                isEdge = false;
            }
            std::vector<bool> newCell = { true, isEdge };

            if ((int)i + 1 > maze.size()) {
                std::vector<std::vector<bool>> newRow = { newCell };

                maze.push_back(newRow);
            }
            else {
                maze[i].push_back(newCell);
            }
        }
    }
}

void Maze::printMaze() {
    for (int i = 0; i < maze.size(); i++) {
        for (int j = 0; j < maze[i].size(); j++) {
            if (maze[i][j][0]) {
                std::cout << "##";
            }
            else {
                std::cout << "  ";
            }
        }
        std::cout << std::endl;
    }
}

void Maze::setStartandEnd(bool jeff) {
    int axis;
    int side;
    if (!jeff) {
        axis = rand() % 2;
        side = rand() % 2;

        Maze::startSide = side;
        Maze::startAxis = axis;
    }
    else {
        bool done = false;

        while (!done) {
            axis = rand() % 2;
            side = rand() % 2;

            if (axis != startAxis || side != startSide) {
                done = true;
            }
        }
    }
    std::vector<int> place = { 0, 0 };

    if (!side) {
        place[!axis] = 0;
    }
    else {
        place[!axis] = mazeSize[!axis] - 1;
    }
    place[axis] = 2 * (rand() % ((mazeSize[axis] + 1) / 2 - 2)) + 1;

    if (!jeff) {
        algoPath.push_back(place);
    }
    Maze::maze[place[1]][place[0]][0] = false;
    Maze::maze[place[1]][place[0]][1] = true;
}

int main() {
    srand(time(NULL));

    Maze maze;
    maze.initMaze();
    maze.setStartandEnd(false);
    maze.setStartandEnd(true);
    maze.generateMaze();
    maze.printMaze();
    return 0;
}

这是头文件&#34; maze2.h&#34;它包含在代码中:

#pragma once
class Maze {
private:
    int mazeSize[2];

    int startAxis;
    int startSide;

    std::vector<std::vector<int>> algoPath;
    std::vector<std::vector<std::vector<bool>>> maze;
    std::vector<int> place;

public:

    bool randDirection(bool);
    bool validInt(char*);
    void generateMaze();
    void initMaze();
    void printMaze();
    void setStartandEnd(bool);
};

我已经通过调试工具运行了它,它一直运行到这一行:

Maze::maze[place[1]][place[0]][0] = false;

我评论了这一点,看看下一行是否会出现同样的问题,而且确实如此。 当线路尝试运行时,调试器给出了这个错误:

Unhandled exception at 0x1008CAB6 (ucrtbased.dll) in maze2.exe: An invalid parameter was passed to a function that considers invalid parameters fatal.

我相信这一点,以及分段错误,表明代码正在尝试分配尚未分配的内存,但我无法弄清楚原因。我已经宣布了一切,所以它应该在记忆中,但我无法弄清楚为什么会发生这种情况。

1 个答案:

答案 0 :(得分:1)

正如评论指出的那样,此代码未明确初始化mazeSize的值,因此其值为default initialized到{0,0}

运行时

maze.initMaze();

在main中,Maze :: maze将不会正确初始化(for循环不会运行)。这将导致程序超出范围&#34;

时抛出的异常
maze.setStartandEnd(false);

尝试访问Maze :: maze中的第一个元素,因为Maze :: maze仍然是空的(大小为0)。