【问题标题】:Debugging C# - stack overflow exception?调试 C# - 堆栈溢出异常?
【发布时间】:2011-06-06 01:47:29
【问题描述】:

下面是我的战舰游戏代码。我不断收到以下错误:

进程因 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.");
    }
}

}

【问题讨论】:

  • +1 表示 StackOverflowException
  • 第一个问题:为什么Player类有一个棋盘副本? (以及固定大小)。创建一个单独的 Board 类...
  • 哇,谢谢米奇哈哈修复它
  • GetXYZ() 和 SetXYZ() 方法应该被移除,而应该使用属性。请使用正确的局部变量和私有字段命名大小写(即,“行”应该是“行”)。当您还是编码新手时,看看 JetBrain 的 Resharper。它应该对您的命名约定有很大帮助 (jetbrains.com/resharper)。

标签: c# stack-overflow


【解决方案1】:

您的 BattleshipBoard 对象在构建过程中创建一个 Player 对象,而您的 Player 对象在构建过程中创建一个 BattleshipBoard。这会来回迭代,直到您溢出堆栈。

调用:

BattleshipBoard b = new BattleshipBoard();

永远不会返回并导致溢出。

【讨论】:

    【解决方案2】:

    堆栈溢出通常是由无限递归引起的;即函数 A 调用 B 然后 B 和 A 和 A 没有终止条件。

    在您的情况下,它是您的两个类 BattleshipBoardPlayer 的初始化。

    您的Player 会创建一个新的BattleshipBoard,而BattleshipBoard 会创建一个新的Player

    BattleshipBoard 中删除Player p = new Player(); 行,一切都会好起来的。

    【讨论】:

      【解决方案3】:

      当您尝试创建初始 BattleshipBoard 时,会导致无限循环交替创建您的两种类型。

      如果您希望这两个类引用另一个对应的类,那么您可以让您的 Player 类在其构造函数中获取 BattleshipBoard。

      【讨论】:

        【解决方案4】:

        您的BattleShipBoard 有一个Player 有一个BattleShipBoard 有一个Player 有一个BattleShipBoard 有一个[...永远继续... ]

        因此,您有堆栈溢出。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2010-11-27
          • 2010-12-08
          • 2020-11-14
          相关资源
          最近更新 更多