2011-07-17 39 views
0

我不確定堆棧溢出異常是什麼。我以另一種形式調用方法時出現此錯誤。請定義一個堆棧溢出異常 - c#

+2

如果你發佈了一些代碼會更好 - 這樣我們可以做我們真正在這裏做的事情:幫助你解決你的異常,而不是定義容易搜索的術語。 –

回答

7

有時候程序不正常。程序員通過執行一些邏輯來編寫程序,然後測試它是否正常工作。但是,如果程序員在邏輯中犯了錯誤,可能會發生不好的事情。

程序可能出錯的最常見方式之一可能是無限循環。採取這一嘗試添加了第一個ñ整數此示例程序:

static int Sum(int n) 
{ 
    int sum = 0; 
    int i = 1; 
    while (i <= n) 
     sum += i; 
    return sum; 
} 

會發生什麼?錯誤在哪裏?我們忘了增加i,所以它永遠不會超過n。當你運行它時,它會運行並掛起。它永遠不會停止。

但是,如果程序中存在無限循環,並且在該循環中使用資源,則可能會用完資源。讓我們使用遞歸來找到和其他程序:

static int RecursiveSum(int n) 
{ 
    return n + RecursiveSum(n - 1); 
} 

這種方法也是越野車。它也有一個「無限循環」,因爲我們忘記了包含終止條件。我們運行它會發生什麼?

由於StackOverflowException,進程終止。

在C#中,每次調用某個方法時,都會使用一個名爲堆棧的資源。該堆棧允許程序跟蹤誰稱誰,以便在方法返回時返回到正確的位置。方法參數和局部變量也佔用堆棧空間。當方法結束並返回時,它們釋放它們使用的堆棧空間。

問題是堆棧使用內存,所以它不是像時間這樣的無限資源!

因此,有兩種主要方式,程序能夠產生StackOverflowException

  1. 的調用方法調用方法從不返回
  2. 一系列太多的遞歸調用水平的方法的無限循環最終結束,但堆棧首先耗盡

第一個問題由上述第二種方法證明。但是,即使我們修復該方法來添加終止條件,但它將適用於較小的數字,但在產生足夠大的數值n之前,它最終會失敗。

大多數園林種類StackOverflowException s是第一種類型,但如果您在方法中不仔細使用遞歸,那麼您也可能遇到第二個問題。

在調試StackOverflowException調用堆棧通常是這樣的:

... 
Program.RecursiveSum(int n = -7770) Line 26 + 0xf bytes C# 
Program.RecursiveSum(int n = -7769) Line 26 + 0xf bytes C# 
Program.RecursiveSum(int n = -7768) Line 26 + 0xf bytes C# 
Program.RecursiveSum(int n = -7767) Line 26 + 0xf bytes C# 
Program.RecursiveSum(int n = -7766) Line 26 + 0xf bytes C# 
The maximum number of stack frames supported by Visual Studio has been exceeded.  

或有時A電話B這就要求C,然後再調用A,等你只需要找到迴路,設置進行中的斷點,診斷正在發生的事情。

+0

當然,如果C#有一個tail-call發射編譯器,它可能*不會* stackoverflow在這個例子上; p –

+0

哇......這真的有幫助!謝謝! –

6

A stack overflow發生在調用對方的方法過多時。

每當您的代碼調用一個函數時,運行時會將一個條目推入調用棧,標記您調用函數時的位置。當函數結束時,運行時會從堆棧中彈出ntry並返回到那裏。

堆棧溢出時發生堆棧溢出。

1

堆棧溢出是當您用完堆棧空間時。堆棧空間通常被方法調用使用,其中參數值被壓入堆棧(當方法返回時,它們被彈出/從堆棧中移除)。你遇到堆棧溢出的最常見情況是當你有某種遞歸(一種自我調用的方法)時。在每個方法調用中,您會消耗更多的堆棧空間,直到耗盡 - 即發生堆棧溢出。