Отладка C # - исключение переполнения стека? - PullRequest
4 голосов
/ 06 июня 2011

Ниже приведен мой код для игры «Морской бой».Я продолжаю получать следующую ошибку:

Процесс прерван из-за исключения StackOverflowException.,

Он продолжает указывать на

char[,] Grid = new char[10, 10];

Как это можно исправить?

using System; 
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace BattleShip_Jamshid_Berdimuratov
{
class BattleshipBoard
{
    Player p = new Player();
    public void Randomize()
    {
        p.SetGrid(1, 2);
        p.SetGrid(2, 2);
        p.SetGrid(3, 2);
    }

    public void DisplayBoard(char[,] Board)
    {
        int Row;
        int Column;

        Console.WriteLine(" ¦ 0 1 2 3 4 5 6 7 8 9");
        Console.WriteLine("--+--------------------");
        for (Row = 0; Row <= 9; Row++)
        {
            Console.Write((Row).ToString() + " ¦ ");
            for (Column = 0; Column <= 9; Column++)
            {
                Console.Write(Board[Column, Row] + " ");
            }
            Console.WriteLine();
        }

        Console.WriteLine("\n");
    }
}

class Player
{
    char[,] Grid = new char[10, 10];
    public int HitCount = 0;
    public int MissCount = 0;
    int x = 0;
    int y = 0;
    BattleshipBoard b = new BattleshipBoard();

    public int getHitCount()
    {
        return HitCount;
    }
    public int getMissCount()
    {
        return MissCount;
    }
    public void AskCoordinates()
    {
        Console.WriteLine("Enter X");
        string line = Console.ReadLine();
        int value;
        if (int.TryParse(line, out value))
        {
            x = value;
        }
        else
        {
            Console.WriteLine("Not an integer!");
        }

        Console.WriteLine("Enter Y");
        line = Console.ReadLine();
        if (int.TryParse(line, out value))
        {
            y = value;
        }
        else
        {
            Console.WriteLine("Not an integer!");
        }

        try
        {
            if (Grid[x, y].Equals('S'))
            {
                Grid[x, y] = 'H';
                Console.Clear();
                Console.WriteLine("Hit!");
                HitCount += 1;
            }
            else
            {
                Grid[x, y] = 'M';
                Console.Clear();
                Console.WriteLine("Miss!");
            }
        }
        catch
        {
            Console.Clear();
            Console.WriteLine("Error: Please enter numbers between 0 and 9. (Inclusive)");
        }
    }
    public char[,] GetGrid()
    {
        return Grid;
    }
    public void SetGrid(int x, int y)
    {
        Grid[x, y] = 'S';
    }
}

class Program
{
    static void Main(string[] args)
    {
        Console.Title = "BerdShip!";
        Console.WriteLine("Welcome to Berdship!\r\n\r\n");
        Console.WriteLine("What is your name?");
        string name = System.Console.ReadLine();
        Console.WriteLine();
        BattleshipBoard b = new BattleshipBoard();
        Player p = new Player();
        b.Randomize();
        while (p.getHitCount() < 12)
        {
            b.DisplayBoard(p.GetGrid());
            p.AskCoordinates();
        }
        Console.WriteLine("Congratulations, " + name + "! You Win!");
        Console.WriteLine("Thanks for playing BerdShip. Press enter to quit.");
    }
}

}

Ответы [ 4 ]

10 голосов
/ 06 июня 2011

Ваш объект BattleshipBoard создает объект Player во время строительства, а ваш объект Player создает BattleshipBoard во время строительства. Это повторяется вперед и назад, пока вы не переполните стек.

Звонок на:

BattleshipBoard b = new BattleshipBoard();

никогда не вернется и вызовет переполнение.

1 голос
/ 06 июня 2011

Когда вы пытаетесь создать начальную панель BattleshipBoard, это приводит к бесконечному циклу, попеременно создающему ваши два типа.

Если вы хотите, чтобы два класса имели ссылку на другой соответствующий класс, тогда вы можете сделать так, чтобы ваш класс Player взял BattleshipBoard в своем конструкторе.

1 голос
/ 06 июня 2011

Переполнение стека обычно вызывается бесконечным отклонением; то есть функция A вызывает B, а затем B и A и A не имеет условия завершения.

В вашем случае это инициализация двух ваших классов BattleshipBoard и Player.

Ваш Player создает новый BattleshipBoard, а BattleshipBoard создает новый Player!

Удалите строку Player p = new Player(); из BattleshipBoard и все должно быть хорошо.

0 голосов
/ 06 июня 2011

Ваш BattleShipBoard имеет Player, который имеет BattleShipBoard, который имеет Player, который имеет BattleShipBoard, который имеет [ ... продолжаться вечно ... ]

Следовательно, у вас переполнение стека.

...