2009-09-20 55 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