NullReferenceException - Maze Generator Script

I keep getting a NullReferenceException on this C# script I’m writing to generate a maze.

Basically how it works is that I have a two-dimensional array of mazeCell objects (each of which contains four walls, and an isVisited member). I think the comments in the code are enough to explain it, but I’m getting this error on any of the four cases in the switch statement (in the line that says “if (tempCell.isVisited == true) // Check if target cell is visited or not”).

Does anyone know why this is happening? This is my code:
using UnityEngine;
using System.Collections;

public class mazeCell 
{
    public bool isVisited;
    public int topWall;
    public int bottomWall;
    public int rightWall;
    public int leftWall;

    public int heightCoordinate;
    public int widthCoordinate;

    public mazeCell()
    {
        isVisited = false;
        topWall = 1;
        bottomWall = 1;
        rightWall = 1;
        leftWall = 1;
    }

}

public class mazeGenerateScript : MonoBehaviour
{
    // Variables for the wall and position of the wall
    public GameObject wallHorizontal;
    public GameObject wallVertical;
    public int xCoordinate = 0;
    public int zCoordinate = 0;

    // Master variables for the height and width of the entire maze
    public static int height = 15;
    public static int width = 20;

    // An array of mazeCell objects
    public mazeCell[,] mazeCellArray = new mazeCell[height + 1, width + 1];

    // The stack that will hold all the visited mazeCell objects and control the backtracking
    Stack cellStack = new Stack();

    // Total number of cells and number of visited cells
    int totalCells = height * width;
    int visitedCells = 0;

    // Use this for initialization
    void Start()
    {
        // Create a new mazeCell object for each element in the mazeCell[,] array, and set the height and width coordinates accordingly
        for (int i = 0; i < height; i++)
        {
            for (int j = 0; j < width; j++)
            {
                mazeCell tempCell = new mazeCell();
                tempCell.heightCoordinate = i;
                tempCell.widthCoordinate = j;
                mazeCellArray[i, j] = tempCell;
            }
        }

        // Create a random set of height and width coordinates for the starting cell
        int startingHeight = Random.Range(0, height);
        int startingWidth = Random.Range(0, width);

        // Assign starting cell to the default instantiated mazeCell object at the random coordinates generated above
        mazeCell currentCell = mazeCellArray[startingHeight, startingWidth];

        // Loop that actually generates the maze
        while (visitedCells < totalCells)
        {
            bool topVisited = false;
            bool bottomVisited = false;
            bool rightVisited = false;
            bool leftVisited = false;

            while (topVisited == false || bottomVisited == false || rightVisited == false || leftVisited == false)
            {
                int directionToTest = Random.Range(1, 4); // Creates a random number representing a direction. 1 for up, 2 for down, 3 for right, 4 for left
                switch (directionToTest)
                {
                    case 1: // Above current cell
                        if (currentCell.heightCoordinate - 1 < 0) // If out of range, set topVisited = true and continue looping (generating another random direction)
                        {
                            topVisited = true;
                            continue;
                        }
                        else // Not out of range
                        {
                            mazeCell tempCell = new mazeCell();
                            tempCell = mazeCellArray[currentCell.heightCoordinate - 1, currentCell.widthCoordinate]; // Set tempCell to the target cell (above)
                            if (tempCell.isVisited == true) // Check if target cell is visited or not
                            {
                                topVisited = true;
                                continue;
                            }
                            else // Target cell is not visited
                            {
                                currentCell.topWall = 0; // Break top wall of current cell
                                mazeCellArray[currentCell.heightCoordinate, currentCell.widthCoordinate] = currentCell; // Refresh current cell values in master array
                                tempCell.bottomWall = 0; // Break bottom wall of tempCell
                                tempCell.isVisited = true; // Set tempCell to visited
                                cellStack.Push(currentCell); // Push currentCell to the stack
                                currentCell = tempCell; // Set currentCell to tempCell
                                visitedCells++; // Increment the number of visited cells
                                break;
                            }
                        }
                    case 2: // Below current cell
                        if (currentCell.heightCoordinate + 1 > height) // If out of range, set bottomVisited = true and continue looping (generating another random direction)
                        {
                            bottomVisited = true;
                            continue;
                        }
                        else // Not out of range
                        {
                            mazeCell tempCell = new mazeCell();
                            tempCell = mazeCellArray[currentCell.heightCoordinate + 1, currentCell.widthCoordinate]; // Set tempCell to the target cell (below)
                            if (tempCell.isVisited == true) // Check if target cell is visited or not
                            {
                                bottomVisited = true;
                                continue;
                            }
                            else // Target cell is not visited
                            {
                                currentCell.bottomWall = 0; // Break bottom wall of current cell
                                mazeCellArray[currentCell.heightCoordinate, currentCell.widthCoordinate] = currentCell; // Refresh current cell values in master array
                                tempCell.topWall = 0; // Break top wall of tempCell
                                tempCell.isVisited = true; // Set tempCell to visited
                                cellStack.Push(currentCell); // Push currentCell to the stack
                                currentCell = tempCell; // Set currentCell to tempCell
                                visitedCells++; // Increment the number of visited cells
                                break;
                            }
                        }
                    case 3: // Right of current cell
                        if (currentCell.widthCoordinate + 1 > width) // If out of range, set rightVisited = true and continue looping (generating another random direction)
                        {
                            rightVisited = true;
                            continue;
                        }
                        else // Not out of range
                        {
                            mazeCell tempCell = new mazeCell();
                            tempCell = mazeCellArray[currentCell.heightCoordinate, currentCell.widthCoordinate + 1]; // Set tempCell to the target cell (right)
                            if (tempCell.isVisited == true) // Check if target cell is visited or not
                            {
                                rightVisited = true;
                                continue;
                            }
                            else // Target cell is not visited
                            {
                                currentCell.rightWall = 0; // Break right wall of current cell
                                mazeCellArray[currentCell.heightCoordinate, currentCell.widthCoordinate] = currentCell; // Refresh current cell values in master array
                                tempCell.leftWall = 0; // Break left wall of tempCell
                                tempCell.isVisited = true; // Set tempCell to visited
                                cellStack.Push(currentCell); // Push currentCell to the stack
                                currentCell = tempCell; // Set currentCell to tempCell
                                visitedCells++; // Increment the number of visited cells
                                break;
                            }
                        }
                    case 4: // Left of current cell
                        if (currentCell.widthCoordinate - 1 < 0) // If out of range, set leftVisited = true and continue looping (generating another random direction)
                        {
                            leftVisited = true;
                            continue;
                        }
                        else // Not out of range
                        {
                            mazeCell tempCell = new mazeCell();
                            tempCell = mazeCellArray[currentCell.heightCoordinate, currentCell.widthCoordinate - 1]; // Set tempCell to the target cell (above)
                            if (tempCell.isVisited == true) // Check if target cell is visited or not
                            {
                                leftVisited = true;
                                continue;
                            }
                            else // Target cell is not visited
                            {
                                currentCell.leftWall = 0; // Break left wall of current cell
                                mazeCellArray[currentCell.heightCoordinate, currentCell.widthCoordinate] = currentCell; // Refresh current cell values in master array
                                tempCell.rightWall = 0; // Break right wall of tempCell
                                tempCell.isVisited = true; // Set tempCell to visited
                                cellStack.Push(currentCell); // Push currentCell to the stack
                                currentCell = tempCell; // Set currentCell to tempCell
                                visitedCells++; // Increment the number of visited cells
                                break;
                            }
                        }
                }
            }
            // If every surrounding cell is visited, backtrack along the stack
            if (topVisited == true && bottomVisited == true && rightVisited == true && leftVisited == true)
                currentCell = (mazeCell)cellStack.Pop();
        }

        for (int x = 0; x < height; x++)
        {
            for (int y = 0; y < width; y++)
            {
                mazeCell tempCell = new mazeCell();
                tempCell = mazeCellArray[x, y];
                if (tempCell.topWall == 0)
                    Instantiate(wallHorizontal, new Vector3(xCoordinate, 0, zCoordinate), Quaternion.identity);
                if (tempCell.bottomWall == 0)
                    Instantiate(wallHorizontal, new Vector3(xCoordinate, 0, zCoordinate + 16), Quaternion.identity);
                if (tempCell.leftWall == 0)
                    Instantiate(wallVertical, new Vector3(xCoordinate, 0, zCoordinate), Quaternion.identity);
                if (tempCell.rightWall == 0)
                    Instantiate(wallVertical, new Vector3(xCoordinate + 16, 0, zCoordinate), Quaternion.identity);
                xCoordinate = xCoordinate + 16;
            }
            zCoordinate = zCoordinate + 16;
        }
    }

    // Update is called once per frame
    void Update()
    {

    }
}

Your array mazeCellArray is 1 item higher and wider than height and width.

 public mazeCell[,] mazeCellArray = new mazeCell[height + 1, width + 1];

When you populate it you only put in height by width mazeCells, so there is a row and column in the array which is empty.

// Create a new mazeCell object for each element in the mazeCell[,] array, and set the height and width coordinates accordingly
for (int i = 0; i < height; i++)
{
    for (int j = 0; j < width; j++)
    {

As soon as your builder loop hits one of the empty cells, it correctly enough has a null ref exception.