2010-04-14 122 views
2

我必須設計和實現一個Fortran例程來確定正方形格上的簇的大小,並且遞歸編寫子例程看起來非常方便。然而,每當我的晶格尺寸增長超過一定的值(大約200 /邊)時,子程序始終發生段錯誤。這是我的集羣檢測程序:Fortran遞歸分段錯誤

RECURSIVE SUBROUTINE growCluster(lattice, adj, idx, area) 
    INTEGER, INTENT(INOUT) :: lattice(:), area 
    INTEGER, INTENT(IN)  :: adj(:,:), idx 

    lattice(idx) = -1 
    area = area + 1 

    IF (lattice(adj(1,idx)).GT.0) & 
     CALL growCluster(lattice,adj,adj(1,idx),area) 

    IF (lattice(adj(2,idx)).GT.0) & 
     CALL growCluster(lattice,adj,adj(2,idx),area) 

    IF (lattice(adj(3,idx)).GT.0) & 
     CALL growCluster(lattice,adj,adj(3,idx),area) 

    IF (lattice(adj(4,idx)).GT.0) & 
     CALL growCluster(lattice,adj,adj(4,idx),area) 
END SUBROUTINE growCluster 

其中ADJ(1,n)表示會場n,ADJ(2,n)的北鄰代表西部等。什麼會導致不規則的段錯誤行爲?對於大的晶格尺寸,集羣是否「太大」?

回答

3

我想你會遇到堆棧溢出。如果你的格子每邊超過200單位,那就是40,000單位,這意味着你要遞歸40,000次。根據您的堆棧大小和堆棧幀大小,您可能會很容易地耗盡堆棧空間。

您必須將您的算法轉換爲使用較少堆棧空間才能處理較大格子的算法。 Wikipedia提供了一些實現(以僞代碼)關於如何進行洪水填充而不吹動堆棧的實現。

+0

這絕對是一個堆棧溢出 - 我開始搞亂(低於最優)的ulimit -s選項,並「解決」了這個問題,但我認爲其他洪泛填充算法在長期跑。感謝您的鏈接! – 2010-04-15 13:26:38

+2

應該有一個徽章在技術相關的環境中說'堆棧溢出' – lurscher 2010-08-13 19:20:57

1

1)你有沒有試過編譯,然後運行下標範圍檢查打開?只是爲了確保大尺寸不會揭示代碼跨越數組邊界進入非法內存的錯誤。這是一個簡單的檢查。

2)請注意您的程序運行內存不足的可能性:嘗試增加每個進程的堆棧大小限制。如何做到這一點取決於操作系統 - 在這裏搜索或谷歌,或告訴我們您的操作系統。