2009-09-20 145 views
3

我什至不知道是什么导致它在我的应用程序。它是什么?我创建了一个新的类实例(该类在另一个文件中),但是在我第一次调用一个方法时,它抛出了一个StackOverFlow异常。什么是vb.net中的StackOverFlow异常?

我认为唯一会合乎逻辑地抛出一个stackoverflow例外的是,如果有人低估了Jon Skeet。

但现在严重,这是什么?我通过在第一个类的相同文件中创建另一个类并使用它为我调用方法来解决此问题。

+0

也许你的错误和一些来源的转储将帮助我们回答你的这个谜题。 – klabranche 2009-09-20 03:18:18

+2

投票Jon实际上导致BSOD。 :) – klabranche 2009-09-20 03:18:51

+0

不会回去重新打破我的代码,因为它不是在源代码控制之下,我不想破坏可行的东西。我半担心乔恩现在会看到这个问题哈哈。 – Cyclone 2009-09-20 03:27:39

回答

6

作为一般规则,堆栈溢出异常是由递归算法引起的,递归深度超过(通常)固定堆栈限制。这通常是算法中存在错误的结果,但也可能是由于算法过于“深入”的数据结构造成的。

下面是一个错误递归的例子(没有特别的PL)。

function int length(list l) { 
    if (empty(l)) { 
     return 0; 
    } else { 
     return 1 + length(l); // should be 'return 1 + length(tail(l)); 
    } 
} 

任何非空列表的调用长度都会导致典型编程语言的堆栈溢出。但即使你纠正了这个错误,调用长列表的方法也可能导致堆栈溢出。

(唯一的例外是当您使用的语言......或更严格的编译器...,支持尾递归优化。)

+0

该算法设置自己调用次数不超过100次,为什么会抛出?请注意,只有在其他文件内部出现时,才会从同一个文件中执行任何操作。 – Cyclone 2009-09-20 03:24:35

+0

你必须向我们展示代码才能得到答案。 – 2009-09-20 03:26:16

+0

我很快在我的网站上有源代码,当我尝试添加多个子窗口时,我正在与MDI混淆并且有问题的代码被调用,父窗口的主类中的For循环被设置为小于100时间不惜一切代价。什么应该将addchild的子调用移动到同一个文件中呢? – Cyclone 2009-09-20 03:29:42

2

StackOverFlows例外的是正是他们听起来像,栈溢出。通常这是因为你的方法有循环依赖。例如方法A调用B和B调用A.或者它可以是一个没有基本情况的递归方法。

2

没有看到代码,不可能知道为什么会发生这种情况,但当线程溢出其调用堆栈时会抛出StackOverflowException。这通常发生在一个方法递归地调用自身而没有任何有条件的中断时创建无限递归。由于每次递归都会创建一个新的堆栈帧,无限递归在理论上会创建无限数量的堆栈帧,我相信您现在可以明白为什么“堆栈溢出”这个词是恰当的。

4

stackoverflow异常是当你超过分配的堆栈大小,这通常发生在递归调用方法,永远不会离开,它也可能是由各种模糊的方法链造成的。问题是你可能在对象中有以下几点。

void MyMethod() 
{ 
    MyMethod(); 
} 

的调用会吃,从来没有自由使用,因为电话永远不会结束的执行和入口点必须保持的堆栈空间。

P.S. SO被命名为特定的异常(这是基本的,不限于.NET),它只是开发者网站的一个聪明的名字。

+0

大声笑,我知道它是因此而命名的,这也是一种双关语,因为这个logo是一堆满满的论文,即收件箱中的工作太多,而且您需要帮助。 – Cyclone 2009-09-20 03:23:28

1

这通常是由递归调用的递归调用永远不会终止的函数引起的。你可以通过几种方式得到这个。一种方法可能是没有基本情况的递归算法,另一种常见方法是创建对象A和B,在对象的构造函数中创建对象之一,等等。

我建议您逐步调试并找出:)

2

堆栈是计算机存储当前正在调用的函数列表以及使用的变量和参数的位置。因此,如果函数Main调用函数A,然后函数A调用函数B,并且它们使用变量c,d和e,则堆栈将包含所有这些信息。但是,堆栈只有这么大。因此,如果函数B调用函数C,函数C调用函数D ...等,最后会有数百个嵌套函数,最终,堆栈将“溢出” - 没有足够的空间来存储另一个函数调用。

正如其他人所指出的,这通常发生在递归函数(其中函数B调用函数B,然后调用函数B ...) - 最终,堆栈将溢出。您将需要找到正在调用的递归函数的位置,以及为什么它在应该的时候不会退出递归循环。

当然,问题可能不是它是一个错误的递归算法 - 它可能只是因为函数调用的数量超过了堆栈的大小。所以如果你的算法有可能将递归函数调用几百次,那可能就是这样。

0

我最近将一个旧的VB6应用程序移植到了VB.NET中,该应用程序使用了一个可怕的递归函数对大量的数据进行排序。算法很好,但执行始终导致堆栈溢出错误。经过很多的调整之后,我意识到VB在代码背后做了很多魔术:简单类型铸造带有价格。所以递归函数在后期绑定上过于依赖,而不是使用类型变量,这导致大量的投射,解析等开销(一行代码可能会调用2到10个函数......)显然,使堆栈溢出。

TL; DR:使用DirectCast()和静态绑定(类型化变量)来防止VB在运行时以递归函数泛滥堆栈。

0

我有这个问题发生,我注意到我错误键入lstEncounter。正如我在我的C++类中学到的那样,问题在于基本使用相同参数调用自身的递归算法。我的例子,我得到的错误:

Property Encounter(ByVal N As Integer) 
    Get 
     If N < lstEncounters.Count Then 
      Return Encounter(N) 
     Else 
      Return Nothing 
     End If 
    End Get 
    Set(value) 
     lstEncounters(N) = value 
    End Set 
End Property 
-1

我有一个Stackoverflow错误。 我正在使用一个例程,将1加到一个计数器,然后重新调用相同的例程。 大约每2500至3000个循环我得到了stackoverflow错误。 我添加了一个DO ...循环调用的程序中,我使用VB快递:

BEFORE:

Public Sub mainloop() 

Dim cntr as integer 

If cntr >= 5000 (I just picked a number at random) 

    me.close (I close the program) 

...    (This is where I would manipulate the cntr for diff 
results) 

cntr = cntr + 1 (increment the cntr) 

mainloop()  (re call my loop) 

End IF 

End Sub 

(如我之前所说的,经过约2500-3000我会得到错误#1 )

AFTER:(将这个执行第一)

Dim LoopCntr as integer 

Do While LoopCntr <= 40000 (this my number.. Use your own number) 

If LoopCntr > 40000 Then 

     Exit Do 
End If 

mainloop()  (The mainloop() has not been changed just the method of calling it) 
LoopCntr = LoopCntr + 1 

Loop 

me.close  (When LoopCntr reaches max it closes the program) 

(添加Do..Loop后,我的程序运行时间40000无 “#1”)

+0

请在编辑器中高亮显示您的代码并将其标记为实际代码! – 2017-07-01 17:58:32