2013-08-20 50 views
3

一個小測試程序在linux 64bit上用gfortran(4.4.5)返回一個段錯誤。 n = 2_8 ** 22_8時不存在故障。 Gdb表示在循環的第一次迭代期間,函數mylen中出現了分段錯誤。Gfortran:長字符的分段錯誤

allocate, stat=   0 
size :    8388608 
len, switch=false :    8388608 
Segmentation fault 

感謝

function mylen(abc,n, switch) 

implicit none 

logical, intent(in) :: switch 
integer(kind=8), intent(in) :: n 
logical, dimension(1:n), intent(in) :: abc 
integer(kind=8) :: mylen 
character(len=size(abc,dim=1,kind=8)) :: tmp 
integer(kind=8) :: i 

mylen=len(tmp,kind=8) 
if (switch) then 
    do i=1,len(tmp,kind=8) 
    tmp(i:i)='a' 
    enddo 
endif 

end function mylen 

program test 

implicit none 

integer(kind=8) :: n 
logical, allocatable :: abc(:) 
integer(kind=8) :: mylen 
integer :: ierr 

n=2_8**23_8 
allocate(abc(n),stat=ierr) 
print *,'allocate, stat=',ierr 
print *,'size :', size(abc,dim=1,kind=8) 
print *,'len, switch=false :', mylen(abc,n,.false.) 
print *,'len, switch=true :', mylen(abc,n,.true.) 

end program test 
+2

我在Ubuntu 10.04上發現gfortran 4.8.1版本沒有問題。你能更新gfortran嗎? – darthbith

+0

不幸的是,否: -/ – user1824346

+1

您可能會嘗試安裝備用編譯器,而不更新與OS一起安裝的編譯器。看到這裏:http://gcc.gnu.org/wiki/GFortranBinaries如果你嘗試這個,你可能必須設置一些環境變量(LIBRARY_PATH或類似)。 – 2013-08-20 14:51:11

回答

4

我測試了,並意識到如果字符數組太大,你吹堆棧。如果使用可分配的長度字符串並將其分配在「mylen」的頂部,則它將放在堆上並且程序正常工作。

+0

不錯的解決方案。你能告訴我「ulimit -a」中的堆棧部分是否對錯誤負責?謝謝 – user1824346

+1

@Sean。當我寫下我的評論時,你已經找到了:-) – 2013-08-21 07:21:05

+0

@ user1824346,我不確定「ulimit -a」會在這裏幫助你很多:實際上,使用-a,所有限制都達到它們的最大值,並且存在甚至在這種情況下(甚至可能取決於機器和操作系統,我認爲我曾看過一次64MB,但您可以檢查「限制」)。你最好不要依賴這個,並聲明可分配數組。無論如何,它不會改變任何程序邏輯。 – 2013-08-21 07:25:48