2016-11-07 116 views
2

執行以下代碼時碰到一個SEG故障:分段故障現出尺寸數組

program test 

call sub ('dave') 

end program test 


subroutine sub (arr) 

character (*) :: arr 
character (20) :: upperc 

arr = upperc (arr) 

return 

end subroutine sub 


character (*) function upperc (str) 

integer i, l 
character (*) :: str 

upperc = str 
l = len (str) 
do i = 1, l 
    icode = ichar (str (i:i)) 
    if ((icode >= ichar ('a')).and.(icode <= ichar ('z'))) then 
    upperc (i:i) = char (ichar ('A') + icode - ichar('a')) 
    end if 
enddo 

return 

end function upperc 

上下面的行發生賽格故障:

arr = upperc (arr) 

這裏的彙編和GDB運行時輸出:

[[email protected] ~]$ gfortran -g -Wall test.f90 
[[email protected] ~]$ gdb 
GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-80.el7 
Copyright (C) 2013 Free Software Foundation, Inc. 
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> 
This is free software: you are free to change and redistribute it. 
There is NO WARRANTY, to the extent permitted by law. Type "show copying" 
and "show warranty" for details. 
This GDB was configured as "x86_64-redhat-linux-gnu". 
For bug reporting instructions, please see: 
<http://www.gnu.org/software/gdb/bugs/>. 
(gdb) file ./a.out 
Reading symbols from /home/dave/a.out...done. 
(gdb) run 
Starting program: /home/dave/./a.out 

Program received signal SIGSEGV, Segmentation fault. 
0x00007ffff70f1fa3 in __memmove_ssse3_back() from /lib64/libc.so.6 
Missing separate debuginfos, use: debuginfo-install glibc- 2.17-106.el7_2.8.x86_64 libgcc-4.8.5-4.el7.x86_64 libgfortran-4.8.5-4.el7.x86_64 libquadmath-4.8.5-4.el7.x86_64 
(gdb) backtrace 
#0 0x00007ffff70f1fa3 in __memmove_ssse3_back() from /lib64/libc.so.6 
#1 0x000000000040078c in sub (arr='dave', _arr=4) at test.f90:13 
#2 0x00000000004008e9 in test() at test.f90:3 
#3 0x000000000040091f in main (argc=1, argv=0x7fffffffe7b3) at test.f90:5 
#4 0x00007ffff6fc3b15 in __libc_start_main() from /lib64/libc.so.6 
#5 0x0000000000400669 in _start() 
(gdb) q 
A debugging session is active. 

    Inferior 1 [process 20941] will be killed. 
[[email protected] ~]$ 

我得到一個有趣的感覺,它與我傳遞一個字面意思有關,但也許不。

在試圖解決這個問題,我嘗試以下相反,它工作正常:

program test2 

character(20) text 

text = 'dave' 

call sub (text) 

end program test2 


subroutine sub (arr) 

character (*) :: arr 
character (20) :: upperc 

arr = upperc (arr) 

return 

end subroutine sub 


character (*) function upperc (str) 

integer i, l 
character (*) :: str 

upperc = str 
l = len (str) 
do i = 1, l 
    icode = ichar (str (i:i)) 
    if ((icode >= ichar ('a')).and.(icode <= ichar ('z'))) then 
    upperc (i:i) = char (ichar ('A') + icode - ichar('a')) 
    end if 
enddo 

return 

end function upperc 

誰能告訴我是怎麼回事?

+0

是的,它與通過文字做改變。您正在嘗試更改常量的值。嘗試將'intent(inout)'放在虛擬參數上來查看。 – francescalus

+1

在[此相關問題](http://stackoverflow.com/q/16457423)的答案中有很多細節(儘管在稍微不同的設置中,但仍然適用於此)。 – francescalus

回答

2

問題是子程序sub從程序test2寫入變量text。如果您沒有給第一個程序test中的sub而只是'dave'這樣的變量賦予一個變量,那麼Fortran意圖覆蓋內存中未被分配爲變量的區域。這導致分段錯誤。

下面你看到你的工作示例。注意兩個變化:

  1. text設置爲6字符,而不是20。這樣做是爲了證明事情仍然適合在一起的長度,如子程序sub需要任意長度的參數。

  2. 我們寫變量text的控制檯2倍的值,它是由call sub(text)

program test3 

character(6) text 

text = 'dave' 

write(*,*) text 

call sub (text) 

write(*,*) text 

end program test3 


subroutine sub (arr) 

character (*) :: arr 
character (20) :: upperc 

arr = upperc (arr) 

return 

end subroutine sub 


character (*) function upperc (str) 

integer i, l 
character (*) :: str 

upperc = str 
l = len (str) 
do i = 1, l 
    icode = ichar (str (i:i)) 
    if ((icode >= ichar ('a')).and.(icode <= ichar ('z'))) then 
    upperc (i:i) = char (ichar ('A') + icode - ichar('a')) 
    end if 
enddo 

return 

end function upperc