假定大小数组

时间:2016-11-07 19:32:33

标签: segmentation-fault fortran gfortran

执行以下代码时出现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

seg错误发生在以下行:

arr = upperc (arr)

这里是编译和GDB运行时输出:

[dave@VM-15 ~]$ gfortran -g -Wall test.f90
[dave@VM-15 ~]$ 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.
[dave@VM-15 ~]$

我觉得这与我传递文字的事实有关,但可能没有。

为了解决这个问题,我尝试了以下方法,它运行正常:

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

有谁能告诉我发生了什么事?

1 个答案:

答案 0 :(得分:2)

问题是子例程sub从程序text写入变量test2。如果您没有将变量作为sub的agrument,而只是'dave',就像在第一个程序test中那样,Fortran打算覆盖内存中的一个区域,该区域未被指定为变量。这导致了分段错误。

下面你看到你的工作示例。请注意两个变化:

  1. 字符text的长度设置为6而不是20.这样做是为了证明事物仍然适合在一起,因为子例程sub采用任意长度的参数。

  2. 我们将变量text的值写入控制台的2倍,并由call sub(text)

  3. 更改

    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