为什么我得到这个堆栈溢出异常
本文关键字:堆栈 栈溢出 异常 为什么 | 更新日期: 2023-09-27 18:12:30
我正在编写《俄罗斯方块》的克隆,这是我真正做过的最大的项目。在实现行删除代码时,我已经开始收到堆栈溢出异常。我认为这可能与我庞大的集合或Linq的低效率使用有关。下面是导致问题的具体方法:
void MoveAllAboveDown(int row)
{
List<Block> newBlockList = new List<Block>();
for (int rowCheck = row; rowCheck > _VertOffset; --rowCheck)
{
for (int i = _HorizOffset; i < _HorizOffset + _Width; ++i)
{
//If the spot above this is filled
if (_blockList.Where(block => block.Contains(new Vector2(i, rowCheck - 1))).ToList().Count > 0)
{
//insert block here
newBlockList.Add(new Block(new Vector2(i, rowCheck), new[,] { { true } }, Color.Black, _texture));
}
else
{
var list = _blockList.Where(tempBlock => tempBlock.Contains(new Vector2(i, rowCheck - 1))).ToList();
if (list.Count > 0)
list.ElementAt(0).Delete(new Vector2(i, rowCheck - 1));
}
}
}
for (int rowToDelete = row; rowToDelete > _VertOffset; --rowToDelete)
{
DeleteRow(rowToDelete);
}
foreach (Block block in newBlockList)
{
_blockList.Add(block);
}
}
如果我能弄清楚如何(甚至使用一个单独的网站,如果我必须),我将附加整个源。
如果你喜欢的话,我真的不介意有人来看看整个代码库,告诉我我写错了什么(比如命名约定、算法等)。显然,这不是这个网站的目的,但我想我应该把它扔进去,因为我无论如何都要攻击代码库。
编辑:下面是主要的游戏文件:http://pastebin.com/PqVAS56U
下面是剩下的代码:http://pastebin.com/JjBKZgwN
Edit2:我相信这是一个堆栈跟踪:
'Tetris.exe' (Managed (v4.0.30319)): Loaded 'C:'Windows'Microsoft.Net'assembly'GAC_32'mscorlib'v4.0_4.0.0.0__b77a5c561934e089'mscorlib.dll', Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'Tetris.exe' (Managed (v4.0.30319)): Loaded 'C:'Users'Patrick'Desktop'OldComp'Users'patrick'Documents'Visual Studio 2010'Projects'Tetris'Tetris'Tetris'bin'x86'Debug'Tetris.exe', Symbols loaded.
'Tetris.exe' (Managed (v4.0.30319)): Loaded 'C:'Windows'Microsoft.Net'assembly'GAC_32'Microsoft.Xna.Framework.Game'v4.0_4.0.0.0__842cf8be1de50553'Microsoft.Xna.Framework.Game.dll'
'Tetris.exe' (Managed (v4.0.30319)): Loaded 'C:'Windows'Microsoft.Net'assembly'GAC_32'Microsoft.Xna.Framework.Graphics'v4.0_4.0.0.0__842cf8be1de50553'Microsoft.Xna.Framework.Graphics.dll'
'Tetris.exe' (Managed (v4.0.30319)): Loaded 'C:'Windows'Microsoft.Net'assembly'GAC_32'Microsoft.Xna.Framework'v4.0_4.0.0.0__842cf8be1de50553'Microsoft.Xna.Framework.dll'
'Tetris.exe' (Managed (v4.0.30319)): Loaded 'C:'Windows'Microsoft.Net'assembly'GAC_MSIL'Microsoft.Xna.Framework.Input.Touch'v4.0_4.0.0.0__842cf8be1de50553'Microsoft.Xna.Framework.Input.Touch.dll'
'Tetris.exe' (Managed (v4.0.30319)): Loaded 'C:'Windows'Microsoft.Net'assembly'GAC_MSIL'System.Drawing'v4.0_4.0.0.0__b03f5f7f11d50a3a'System.Drawing.dll', Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'Tetris.exe' (Managed (v4.0.30319)): Loaded 'C:'Windows'Microsoft.Net'assembly'GAC_MSIL'System'v4.0_4.0.0.0__b77a5c561934e089'System.dll', Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'Tetris.exe' (Managed (v4.0.30319)): Loaded 'C:'Windows'Microsoft.Net'assembly'GAC_MSIL'System.Windows.Forms'v4.0_4.0.0.0__b77a5c561934e089'System.Windows.Forms.dll', Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'Tetris.exe' (Managed (v4.0.30319)): Loaded 'C:'Windows'Microsoft.Net'assembly'GAC_MSIL'Microsoft.Xna.Framework.GamerServices'v4.0_4.0.0.0__842cf8be1de50553'Microsoft.Xna.Framework.GamerServices.dll'
'Tetris.exe' (Managed (v4.0.30319)): Loaded 'C:'Windows'Microsoft.Net'assembly'GAC_MSIL'System.Core'v4.0_4.0.0.0__b77a5c561934e089'System.Core.dll', Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
Process is terminated due to StackOverflowException.
The program '[7484] Tetris.exe: Managed (v4.0.30319)' has exited with code 0 (0x0).
如果不跟踪其余的代码,我怀疑部分原因是在:
中使用了row
而不是rowToDelete
for (int rowToDelete = row; rowToDelete > _VertOffset; --rowToDelete)
{
// DeleteRow(row); // Woops! Typo
DeleteRow(rowToDelete);
}
编辑:如果不在那里,那么很可能在DeleteRow中。
我没有看到您减少传递给MoveAllAboveDown()
然后传递给DeleteRow()
的row
的值。您的DeleteRow()
函数再次使用相同的row
号码调用MoveAllAboveDown()
。
所以它们会一直互相调用直到StackOverflow。
我认为你得到一个堆栈跟踪的原因是MoveAllAboveDown(int row)调用DeleteRow(int row)调用MoveAllAboveDown(int row)创建一个无限循环,正如已经由cornerback84指出的。
这里有一些其他的技巧:
- 您在问题中编辑的不是堆栈跟踪,而是跟踪输出。
- 堆栈跟踪表示打印出调用堆栈,它将显示嵌套的当前执行的方法。
- 在Visual Studio菜单中选择Debug> Windows> call stack查看调用堆栈。要复制调用堆栈以粘贴到问题中,请在异常助手对话框中单击"复制异常详细信息"。
- 既然你问了关于命名约定等的评论,我建议你看看:
- Microsoft命名指南
- StyleCop(这是优秀的!)
- 作为额外提示,检查FxCop也-你会学到很多,保证:)