关闭输入文件时出现 Fortran 分段错误
Fortran-Segmentation Fault Upon Closing an Input File
希望有人能帮我解决这个问题。将不胜感激。
背景。我正在为我们的研究小组扩展一段遗留代码,进行一些传热、热对流等类型的数值建模。我想要做的是读取一个温度输入文件,这样我就可以随着模型的进展及时调整模型的温度。虽然该信息在很大程度上是无关紧要的。在尝试关闭我打开并正在读取的文件时,我一直遇到分段错误。我附上了下面的代码以及典型的温度输入文件的样子(但由于会有数千个数据点,因此大大简化了)。在消除分段错误方面,我们将不胜感激 and/or 更正代码以使其更高效。
subroutine Read_Temp_Input(Temp_in)!(dt)!(filename)!,dt,Temp_out)
implicit none
character*80 :: filename
integer, parameter :: dp = selected_real_kind(15)
real(kind=dp), allocatable, dimension(:,:) :: Temp_in, Temp_out
integer :: i,j,ierror,n
real (kind=dp) :: in_time, in_temp, dt, inter_time, inter_temp, max_time
character*80 :: line
!Variable definitions
!in_time is the time given from the input file
!in_temp is the temp given from the input file
!inter_time is the interpolated time using dt, max_time, and linear interpolation
!inter_temp is the interpolated temp using dt, max_time, and linear interpolation
!max_time is the largest time value in the input file
!dt is the time step utilized in the simulation, provided by main routine
!read in the temperature input file
filename = "temps.txt"
Open(UNIT=1,FILE=filename,ACTION="Read")
!Determine the size of the necessary allocation
n = 0
do
Read(1,*,iostat=ierror) in_time, in_temp
if (ierror.ne.0) then
exit
else
print*, in_time, in_temp
n = n + 1
endif
enddo
!Allocate the Temp_in array to a n x 2 array.
allocate(Temp_in(n,2))
close(unit=1)
Open(UNIT=1,FILE=filename,ACTION="Read")
n = 0
do
Read(1,*,iostat=ierror) in_time, in_temp
if (n.ne.0) then
if (ierror.ne.0) then
exit
else
Temp_in(n-1,0) = in_time
Temp_in(n-1,1) = in_temp
endif
endif
n = n + 1
enddo
dt = 0.5_dp
print*, 'is the fault before here?'
close(1)
print*, 'is the fault here?'
end subroutine
温度文件
Time Temp
1 300
2 400
3 500
5 600
附件也是我得到的输出。我会及时摆脱随机打印语句,只是用它们来测试我的代码在哪里出错。
enter image description here
感谢您的帮助,不胜感激。
Fortran 数组默认从 1 开始,您的示例中的 Temp_in
也是如此。所以行
Temp_in(n-1,0) = in_time
Temp_in(n-1,1) = in_temp
会写越界(对于n=1
,两者都是越界,第一个总是越界)。
您可以使用 --check=bounds
标志让编译器为您检查,如果您试图以这种方式访问数组,它将抛出运行时错误。
所以要么将 Temp_in
分配为
allocate(Temp_in(0:n-1,0:1))
或者使用从 1 开始的索引作为解决方案。
更新
此外,在确定条目数时,读取示例 temps.txt
文件的第一行将失败,因为它试图读取两个 real
但却找到了其他内容。因此,您需要在打开文件后进行虚拟读取以读取第一行(或使用与第二个循环中相同的附加检查)
Open(UNIT=1,FILE=filename,ACTION="Read")
! read in the first line and throw it away
read(1,*)
! go on
希望有人能帮我解决这个问题。将不胜感激。
背景。我正在为我们的研究小组扩展一段遗留代码,进行一些传热、热对流等类型的数值建模。我想要做的是读取一个温度输入文件,这样我就可以随着模型的进展及时调整模型的温度。虽然该信息在很大程度上是无关紧要的。在尝试关闭我打开并正在读取的文件时,我一直遇到分段错误。我附上了下面的代码以及典型的温度输入文件的样子(但由于会有数千个数据点,因此大大简化了)。在消除分段错误方面,我们将不胜感激 and/or 更正代码以使其更高效。
subroutine Read_Temp_Input(Temp_in)!(dt)!(filename)!,dt,Temp_out)
implicit none
character*80 :: filename
integer, parameter :: dp = selected_real_kind(15)
real(kind=dp), allocatable, dimension(:,:) :: Temp_in, Temp_out
integer :: i,j,ierror,n
real (kind=dp) :: in_time, in_temp, dt, inter_time, inter_temp, max_time
character*80 :: line
!Variable definitions
!in_time is the time given from the input file
!in_temp is the temp given from the input file
!inter_time is the interpolated time using dt, max_time, and linear interpolation
!inter_temp is the interpolated temp using dt, max_time, and linear interpolation
!max_time is the largest time value in the input file
!dt is the time step utilized in the simulation, provided by main routine
!read in the temperature input file
filename = "temps.txt"
Open(UNIT=1,FILE=filename,ACTION="Read")
!Determine the size of the necessary allocation
n = 0
do
Read(1,*,iostat=ierror) in_time, in_temp
if (ierror.ne.0) then
exit
else
print*, in_time, in_temp
n = n + 1
endif
enddo
!Allocate the Temp_in array to a n x 2 array.
allocate(Temp_in(n,2))
close(unit=1)
Open(UNIT=1,FILE=filename,ACTION="Read")
n = 0
do
Read(1,*,iostat=ierror) in_time, in_temp
if (n.ne.0) then
if (ierror.ne.0) then
exit
else
Temp_in(n-1,0) = in_time
Temp_in(n-1,1) = in_temp
endif
endif
n = n + 1
enddo
dt = 0.5_dp
print*, 'is the fault before here?'
close(1)
print*, 'is the fault here?'
end subroutine
温度文件
Time Temp
1 300
2 400
3 500
5 600
附件也是我得到的输出。我会及时摆脱随机打印语句,只是用它们来测试我的代码在哪里出错。
enter image description here
感谢您的帮助,不胜感激。
Fortran 数组默认从 1 开始,您的示例中的 Temp_in
也是如此。所以行
Temp_in(n-1,0) = in_time
Temp_in(n-1,1) = in_temp
会写越界(对于n=1
,两者都是越界,第一个总是越界)。
您可以使用 --check=bounds
标志让编译器为您检查,如果您试图以这种方式访问数组,它将抛出运行时错误。
所以要么将 Temp_in
分配为
allocate(Temp_in(0:n-1,0:1))
或者使用从 1 开始的索引作为解决方案。
更新
此外,在确定条目数时,读取示例 temps.txt
文件的第一行将失败,因为它试图读取两个 real
但却找到了其他内容。因此,您需要在打开文件后进行虚拟读取以读取第一行(或使用与第二个循环中相同的附加检查)
Open(UNIT=1,FILE=filename,ACTION="Read")
! read in the first line and throw it away
read(1,*)
! go on