陷入奇怪的堆栈溢出

时间:2012-06-07 02:02:02

标签: vb.net visual-studio stack-overflow

我正在用Visual Basic .NET编写这个程序来组织不同的数据字段,我正在通过应用程序设置使用配置文件槽来为用户存储数据。但是,我在SlotSelect.vb类中遇到了堆栈溢出错误。我最好的猜测是为什么会发生这种情况,因为我在下面的代码中使用了错误的变量容器,但我的困境是我不知道具体是什么问题。

vshost所说的代码是溢出的原因是从我在MSDN和其他地方查找的一些代码写的,用于引用其他类中的对象,我尝试使用它的其他变体来查看是否有有什么不同。到目前为止,没有任何工作,并且它不会在编译时停止错误,更不用说在代码标记中 - 只有在它完成构建后在调试中启动应用程序时才捕获它。

这是SlotSelect.vb的酱汁代码。由于大多数其他不相关的课程(以及这一课程)都会导致MainForm.vb,我也会加入其中。 vshost提供的位置,因为错误位于为_MainFormFlaglister.MainForm定义变量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

代码中的问题是什么?

以下是关于我和我的计划的一些其他详细信息。

计算机

  

系统:七台x64 w / AMD Sempron
  编译器:Microsoft Visual Basic 2010 Express

应用

  

框架:Microsoft .NET版本3.5
  根命名空间:Flaglister
  装配名称:Flaglister
  应用程序类型:Windows窗体应用程序

有时候我想的太多了,所以如果答案对很多人来说很明显而且我没有看到,我很抱歉。

修改

这是抛出错误时当前位置的callstack的屏幕截图,以及弹出错误框的另一个屏幕截图。我永远不会猜到要添加这些。

Call stack screenshot

Exception screenshot

3 个答案:

答案 0 :(得分:3)

这里的问题是递归初始化。 MainForm包含:

Private _SlotSelect As New Flaglister.SlotSelect

SlotSelect包含:

Private _MainForm As Flaglister.MainForm = New Flaglister.MainForm

他们不断调用彼此的构造函数,导致堆栈溢出。您可以通过在_MainForm的构造函数中传入SlotSelect作为参数来解决此问题。像这样:

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

    '...

MainForm.vb中,将SlotSelect的构造函数传递给当前实例:

Private _SlotSelect As New Flaglister.SlotSelect(Me)

答案 1 :(得分:2)

我猜这是因为在你的班级中你声明并实例化一个新的MainForm实例

 Private _MainForm As Flaglister.MainForm = New Flaglister.MainForm

然后在MainForm类中声明并实例化SlotSelect类的新实例

 Private _SlotSelect As New Flaglister.SlotSelect

所以这两个类只是“反弹”来回创建彼此的新实例,最终给你堆栈溢出。

答案 2 :(得分:0)

你处在一个无限循环中。

在slotselect中你有

Private _MainForm As Flaglister.MainForm = New Flaglister.MainForm

创建一个新的主窗体,然后在MainForm中创建

Private _SlotSelect As New Flaglister.SlotSelect

创建一个新的slotselect。

将一个对象设为父对象,将一个对象设为子对象,并在构造函数中提交父引用,例如

Class SlotSelect
  Private _MainForm As MainForm
  Sub New(mf as MainForm)
    _MainForm=mf
  End Sub
...
End Class