I'm writing this program in Visual Basic .NET to organize different fields of data, and I'm using profile slots through application settings to store the data for users. But, I ran into a stack overflow error in my SlotSelect.vb
class. My best plausible guess for why this happens is that I'm using the wrong kind of variable container in the below sauce code, but my dilemma is that I don't know what specifically is going wrong.
The code that the vshost is saying is the cause for the overflow was written from some code that I looked up on MSDN and other places for referring to objects in other classes, and I tried using other variants of it to see if it was any different. So far, nothing has worked, and it doesn't stop the error while compiling, much less in the code markup--it only catches it when it starts the application in debug after it finishes building.
Here's the sauce code for SlotSelect.vb
. Since most of the other unrelated classes (and this one) lead into MainForm.vb
, I'll include its sauce too. The location vshost gave as the error is on the line where variable _MainForm
is defined for Flaglister.MainForm
to be used within SlotSelect.vb
.
SlotSelect.vb
Public Class SlotSelect
' Class variables
Private _MainForm As Flaglister.MainForm = New Flaglister.MainForm
Private _SaveSlot As Flaglister.SaveSlot = New Flaglister.SaveSlot
Private _Misc As Flaglister.Misc = New Flaglister.Misc
Private _FlagsTextBox As System.Windows.Forms.TextBox = Flaglister.MainForm.FlagsTextBox
Private _VarsTextBox As System.Windows.Forms.TextBox = Flaglister.MainForm.VarsTextBox
Private _HackNameTextBox As System.Windows.Forms.TextBox = Flaglister.MainForm.HackNameTextBox
Private _RomCodeTextBox As System.Windows.Forms.TextBox = Flaglister.MainForm.RomCodeTextBox
Private _NotesTextBox As System.Windows.Forms.TextBox = Flaglister.MainForm.NotesTextBox
Private _ExpandedCheckBox As System.Windows.Forms.CheckBox = Flaglister.MainForm.ExpandedCheckBox
' Slot selection main execution subs
Friend Sub _0()
Try
' Disable FlagsTextBox
_FlagsTextBox.DeselectAll()
_FlagsTextBox.ClearUndo()
_FlagsTextBox.Clear()
_FlagsTextBox.Enabled = False
' Disable VarsTextBox
_VarsTextBox.DeselectAll()
_VarsTextBox.ClearUndo()
_VarsTextBox.Clear()
_VarsTextBox.Enabled = False
' Disable HackNameTextBox
_HackNameTextBox.DeselectAll()
_HackNameTextBox.ClearUndo()
_HackNameTextBox.Clear()
_HackNameTextBox.Enabled = False
' Disable RomCodeTextBox
_RomCodeTextBox.DeselectAll()
_RomCodeTextBox.ClearUndo()
_RomCodeTextBox.Clear()
_RomCodeTextBox.Enabled = False
' Disable NotesTextBox
_NotesTextBox.DeselectAll()
_NotesTextBox.ClearUndo()
_NotesTextBox.Clear()
_NotesTextBox.Enabled = False
Catch
Call _Misc.ErrorClose()
End Try
End Sub
Friend Sub _1()
Try
' Load flaglist
_FlagsTextBox.DeselectAll()
_FlagsTextBox.ClearUndo()
_FlagsTextBox.Clear()
_FlagsTextBox.Enabled = True
_FlagsTextBox.Text = My.Settings.Flaglist_1
' Load varlist
_VarsTextBox.DeselectAll()
_VarsTextBox.ClearUndo()
_VarsTextBox.Clear()
_VarsTextBox.Enabled = True
_VarsTextBox.Text = My.Settings.Varlist_1
' Load project name
_HackNameTextBox.DeselectAll()
_HackNameTextBox.ClearUndo()
_HackNameTextBox.Clear()
_HackNameTextBox.Enabled = True
_HackNameTextBox.Text = My.Settings.Hackname_1
' Load ROM codename
_RomCodeTextBox.DeselectAll()
_RomCodeTextBox.ClearUndo()
_RomCodeTextBox.Clear()
_RomCodeTextBox.Enabled = True
_RomCodeTextBox.Text = My.Settings.Romcode_1
' Load other notes
_NotesTextBox.DeselectAll()
_NotesTextBox.ClearUndo()
_NotesTextBox.Clear()
_NotesTextBox.Enabled = True
_NotesTextBox.Text = My.Settings.Notes_1
Catch
Call _Misc.ErrorClose()
End Try
End Sub
Friend Sub _2()
Try
' Load flaglist
_FlagsTextBox.DeselectAll()
_FlagsTextBox.ClearUndo()
_FlagsTextBox.Clear()
_FlagsTextBox.Enabled = True
_FlagsTextBox.Text = My.Settings.Flaglist_2
' Load varlist
_VarsTextBox.DeselectAll()
_VarsTextBox.ClearUndo()
_VarsTextBox.Clear()
_VarsTextBox.Enabled = True
_VarsTextBox.Text = My.Settings.Varlist_2
' Load project name
_HackNameTextBox.DeselectAll()
_HackNameTextBox.ClearUndo()
_HackNameTextBox.Clear()
_HackNameTextBox.Enabled = True
_HackNameTextBox.Text = My.Settings.Hackname_2
' Load ROM codename
_RomCodeTextBox.DeselectAll()
_RomCodeTextBox.ClearUndo()
_RomCodeTextBox.Clear()
_RomCodeTextBox.Enabled = True
_RomCodeTextBox.Text = My.Settings.Romcode_2
' Load other notes
_NotesTextBox.DeselectAll()
_NotesTextBox.ClearUndo()
_NotesTextBox.Clear()
_NotesTextBox.Enabled = True
_NotesTextBox.Text = My.Settings.Notes_2
Catch
Call _Misc.ErrorClose()
End Try
End Sub
Friend Sub _3()
Try
' Load flaglist
_FlagsTextBox.DeselectAll()
_FlagsTextBox.ClearUndo()
_FlagsTextBox.Clear()
_FlagsTextBox.Enabled = True
_FlagsTextBox.Text = My.Settings.Flaglist_3
' Load varlist
_VarsTextBox.DeselectAll()
_VarsTextBox.ClearUndo()
_VarsTextBox.Clear()
_VarsTextBox.Enabled = True
_VarsTextBox.Text = My.Settings.Varlist_3
' Load project name
_HackNameTextBox.DeselectAll()
_HackNameTextBox.ClearUndo()
_HackNameTextBox.Clear()
_HackNameTextBox.Enabled = True
_HackNameTextBox.Text = My.Settings.Hackname_3
' Load ROM codename
_RomCodeTextBox.DeselectAll()
_RomCodeTextBox.ClearUndo()
_RomCodeTextBox.Clear()
_RomCodeTextBox.Enabled = True
_RomCodeTextBox.Text = My.Settings.Romcode_3
' Load other notes
_NotesTextBox.DeselectAll()
_NotesTextBox.ClearUndo()
_NotesTextBox.Clear()
_NotesTextBox.Enabled = True
_NotesTextBox.Text = My.Settings.Notes_3
Catch
Call _Misc.ErrorClose()
End Try
End Sub
' Save all slots
Friend Sub SlotSaveAll()
Call _SaveSlot.FlaglistSave()
Call _SaveSlot.VarlistSave()
Call _SaveSlot.HacknameSave()
Call _SaveSlot.RomcodeSave()
Call _SaveSlot.NotesSave()
Call _SaveSlot.ExpandedSave()
End Sub
End Class
MainForm.vb
Public Class MainForm
' Class-level variables
Private _SlotSelect As New Flaglister.SlotSelect
Private _SaveSlot As New Flaglister.SaveSlot
Private _Misc As New Flaglister.Misc
' Startup/Shutdown events
Sub MainForm_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
If Slot0RadioButton.Checked = True Then
Call _SlotSelect._0()
End If
End Sub
Sub MainForm_Deactivate(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Deactivate
My.Settings.Save()
Me.Close()
End Sub
' Form object events
Private Sub Slot0RadioButton_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Slot0RadioButton.CheckedChanged
If Slot0RadioButton.Checked = True Then
Call _SlotSelect._0()
End If
End Sub
Private Sub Slot1RadioButton_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Slot1RadioButton.CheckedChanged
If Slot1RadioButton.Checked = True Then
Call _SlotSelect._1()
End If
End Sub
Private Sub Slot2RadioButton_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Slot2RadioButton.CheckedChanged
If Slot2RadioButton.Checked = True Then
Call _SlotSelect._2()
End If
End Sub
Private Sub Slot3RadioButton_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Slot3RadioButton.CheckedChanged
If Slot3RadioButton.Checked = True Then
Call _SlotSelect._3()
End If
End Sub
Private Sub FlagsTextBox_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles FlagsTextBox.TextChanged
Call _SaveSlot.FlaglistSave()
End Sub
Private Sub VarsTextBox_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles VarsTextBox.TextChanged
Call _SaveSlot.VarlistSave()
End Sub
Private Sub HackNameTextBox_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles HackNameTextBox.TextChanged
Call _SaveSlot.HacknameSave()
End Sub
Private Sub RomCodeTextBox_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RomCodeTextBox.TextChanged
Call _SaveSlot.RomcodeSave()
End Sub
Private Sub NotesTextBox_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles NotesTextBox.TextChanged
Call _SaveSlot.NotesSave()
End Sub
Private Sub ExpandedCheckBox_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ExpandedCheckBox.CheckedChanged
Call _SaveSlot.ExpandedSave()
End Sub
End Class
What's the problem in the code?
Here's some additional details about me and my program.
Computer
System: Seven x64 w/ AMD Sempron
Compiler: Microsoft Visual Basic 2010 Express
Application
Framework: Microsoft .NET version 3.5
Root Namespace: Flaglister
Assembly name: Flaglister
Application Type: Windows Forms Application
Sometimes I think too much, so I'm sorry if the answer is obvious to many and I don't see it.
EDIT
Here's a screenshot of the callstack at its current position when the error is thrown, and another screenshot of the popup error box. I would've never guessed to add these.
The issue here is recursive initialization. MainForm
contains:
Private _SlotSelect As New Flaglister.SlotSelect
And SlotSelect
contains:
Private _MainForm As Flaglister.MainForm = New Flaglister.MainForm
They keep calling each other's constructor, causing your stack overflow. You can fix this by passing in _MainForm
as an argument in SlotSelect
's constructor. Like so:
Public Class SlotSelect
' Class variables
Private _MainForm As Flaglister.MainForm
' (truncated for space)
Public Sub New(ByVal mainForm As Flaglister.MainForm)
Me._MainForm = mainForm
End Sub
'...
And in MainForm.vb
, pass SlotSelect
's constructor the current instance:
Private _SlotSelect As New Flaglister.SlotSelect(Me)