2012-09-01 66 views
0

我最近一直在寫SEC算法(就像這裏的http://18.7.29.232/bitstream/handle/1721.1/4015/HPCES024.pdf?sequence=2)。起初遞歸版本,似乎拋出「堆棧溢出」異常超過200000點。我不知道爲什麼,直到我把它寫在我自己的堆棧上(使用迭代而不是遞歸),並且它在1000000點中工作正常。在指定的內存地址中調用函數。 C++

我相信當我調用函數時,處理器和變量的指令被複制到一些「隨機」分配的內存中。我還認爲,當我有一個類向量的全局變量時,它需要有一些緊湊的內存(如表格)。因爲(在我看來)當內存被分割成小部分時,向量不能「放大」並拋出「堆棧溢出」異常,因此問題在於當我有大量函數調用時(例如在某些遞歸算法中)。

所以我想我可以以某種方式說服C++它應該存儲函數實例的內存。像這裏http://www.parashift.com/c++-faq-lite/placement-new.html製作一些「函數實例」表,所以它不能混淆內存。

可能嗎?

+0

什麼是你的矢量矢量*的*?它有多大?最好的解決方案可能只是使用更合適的集合類。 –

+0

因爲堆棧(用於存儲函數中的局部變量,參數和返回地址)是有限的,所以在對大數據集使用遞歸時應該一直要小心,並且當遞歸到很多時,會得到堆棧溢出異常。你可以通過在堆上分配數據(例如使用'new')而不是使用局部變量來獲得這個數據。載體或類似的集合。 –

+0

它使用兩個10^6浮點數(= 8mb)的表格,一個最大尺寸爲10^6個元素(= 2 * 4mb)的int向量,在「主SEC函數」中有一個int(最大遞歸級別爲10^6 ,這使得4mb)。假設,它使用20mb +一些內存來進行函數調用。它並不多。 –

回答

0

從來沒有vector誰提供堆棧溢出錯誤。 vector在堆上分配它的內存,它可以像你的總內存一樣大(包括虛擬內存)。另一方面,堆棧是一個(相當)小的內存,程序在其上存儲函數局部變量以及其他內容。

當你調用一個函數,這些都是寫在堆棧上的一些數據:

  • 可能還有一些寄存器
  • 堆棧指針
  • 可能還有一些空間,返回值
  • 功能參數如果有的話
  • 基址指針
  • 新函數的局部變量

根據架構/編譯器的不同,也可能有其他數據。

因此,即使是最簡單的函數,也只需調用堆棧中的最小內存量即可。幸運的是,當函數返回時,這些內存再次可用。但是,雖然此功能尚未返回,但這些數據仍然存在。所以如果你遞歸地調用一個函數,所有這些數據都會彼此堆疊在一起。如果你沒有儘快結束你的遞歸函數,你會用完內存,你會得到一個堆棧溢出錯誤。

如果你很好奇,你可以添加額外的變量(確保它們沒有被優化)到你的函數,並看到你得到這個錯誤的點數較少。

您的解決方案,有其他人在評論中說,因此使用迭代方法,基本上使用std::stack例如模擬調用堆棧。

+0

好吧,正如我之前說過的,我已經使用迭代寫了整個算法,而不是遞歸模擬向量堆棧(它工作得很好,但代碼看起來非常糟糕)。只是爲什麼遞歸解決方案不起作用,並希望有一些聰明的解決方案使其能夠以遞歸方式工作。正如我所看到的,沒有。 –

+0

@PanJan,不幸的是,你不能用迭代過多地進行遞歸工作。函數框架(我上面提到的那些數據)是函數調用的一個不可避免的部分。 – Shahbaz