Why am I getting this Stack Overflow exception?
Domanda
I am writing a Tetris clone, which is the largest project I have really done. In implementing the row deletion code, I have begun recieving a stack overflow exception. I think it probably has something to do with my huge collections or horribly inefficient use of Linq. Here is the specific method that is causing the issue:
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);
}
}
I'll attach the entire source if I can figure out how (even using a separate site if I have to).
If you feel like it, I really wouldn't mind if someone were to look at the entire code base and tell me what I do write and wrong (like naming conventions, algorithms, etc.). Obviously this is not what the site is for, but I figured I'd throw this in since I am attacking the code base anyway.
Edit:
Here is the main game file:
http://pastebin.com/PqVAS56U
Here is the rest of the code:
http://pastebin.com/JjBKZgwN
Edit2: I believe this is a stack trace:
'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).
Soluzione
I don't see you decrementing the value of row
that you are passing to MoveAllAboveDown()
and then into DeleteRow()
. Your DeleteRow()
function again calls MoveAllAboveDown()
with same row
number.
So they will keep on calling each other until StackOverflow.
Altri suggerimenti
Without tracing the rest of the code, I suspect part of it is the use of row
instead of rowToDelete
in:
for (int rowToDelete = row; rowToDelete > _VertOffset; --rowToDelete)
{
// DeleteRow(row); // Woops! Typo
DeleteRow(rowToDelete);
}
Edit: If not there, then it is likely in DeleteRow.
I think the reason you're getting a stack trace, is that MoveAllAboveDown(int row) calls DeleteRow(int row) which calls MoveAllAboveDown(int row) creating an infinite loop, as pointed out already by cornerback84.
Here's a couple of other tips:
- What you edited into the question was not the stack trace, but the trace output.
- Stack trace means a print out of the call stack, which will show the nested currently executing methods.
- To view the call stack select Debug > Windows > Call Stack, in the Visual Studio menu.
- To copy the call stack for pasting into questions, click on "Copy exception details" in the Exception Assistant Dialog Box
- Since you asked for comment on naming conventions etc., I'd recommend checking out:
- Microsoft Naming Guidlines
- StyleCop (this is excellent!)
- As a bonus tip, check out FxCop too - you will learn lots, guaranteed :)