我的派生类型代码中的分段错误

时间:2016-04-26 18:52:02

标签: segmentation-fault fortran

我无法解决我的Fortran代码的问题。它编译但在执行期间可靠地死亡(分段错误)。

主程序将我的班级cell_autom实例化为ma。它还将我的类random_pathfinder实例化为pf,并将我的ma实例作为参数传递给它的构造函数:

use ClassCellularAutomata
use ClassRule
use ClassRandomPathfinder
implicit none

class(random_pathfinder), allocatable :: pf
class(cell_autom), allocatable :: ma
integer, parameter :: width = 30
integer, parameter :: T_steps = 3
integer, parameter :: step_dist = 4
double precision, parameter :: goal_score = 0.90

allocate(ma, source = moore_autom(width, width, T_steps))
call ma%rule%generate_random()
call ma%random_seed_field()

allocate(pf, source = random_pathfinder(ma, step_dist, goal_score))
call pf%run_pathfinder()

现在,在pf构造函数语句setupallocate(inst%autom, source = autom)的构造期间发生了分段错误:

module ClassRandomPathfinder
use ClassCellularAutomata
use ClassRule
implicit none

type random_pathfinder
    class(cell_autom), allocatable :: autom
    type(rule) :: goal_rule
    integer :: step_dist
    logical, allocatable :: goal_pattern(:,:)
    logical, allocatable :: steps_done(:)
    double precision :: current_score, goal_score
    integer(kind=4) :: path_length

    contains

    procedure, pass(this) :: run_pathfinder

end type

interface random_pathfinder
    procedure setup
end interface

contains

function setup(autom, step_dist, goal_score) result(inst)
    implicit none
    class(random_pathfinder), allocatable :: inst
    class(cell_autom) :: autom
    integer, intent(in) :: step_dist
    double precision, intent(in) :: goal_score
    integer :: i

    ! Set init values
    allocate(inst%autom, source = autom)
    inst%step_dist = step_dist
    inst%goal_score = goal_score

    ! Setup the random pathfinder
    ! Init goal rule
    inst%goal_rule = inst%autom%rule

    ! Run it once to get the goal pattern
    call inst%autom%run()
    inst%goal_pattern = inst%autom%get_last_pattern()

    ! Reset the automaton
    call inst%autom%reset_to_last_start()

    ! change the rule
    do i = 1, inst%step_dist
        call inst%autom%rule%flip_random_rule_entry()
    end do

end function setup

我的第一个想法是责怪分配声明本身或我的automcell_autom定义。但在我注释掉这一行(以及其他行)之后,分段错误恰好在下一行中发生inst%分配。所以我想问题出在我的random_pathfinder类或它的构造函数上。

我对Fortran的新手很陌生,并且不知道出了什么问题。也许你们中的一个人看到了一个或几个明显的错误。

我正在使用f08和gfortran编译器。另一个问题是gdb并没有在oop程序中停留在我的geany断点上(是的,我使用了-g标志)。

要完成此操作,请参阅我的cell_autom类型定义:

type cell_autom

    ! M x N fields, T_steps time steps
    integer :: M=0, N=0, T_steps=0
    ! set true to export an image array every step
    logical :: export_every_step = .False., print_every_step = .False.
    ! field_a and field_b will be iterated and set alternatingly
    logical, allocatable :: field_a(:,:), field_b(:,:), start_pattern(:,:)
    ! image array holds a 0/1 integer representation of a field
    integer, allocatable :: image_array(:,:)
    ! rule holds the update rule
    class(rule), allocatable :: rule
    ! data_dir is the directory where image and info files will be saved
    character(len=4) :: data_dir

    contains

    procedure, pass(this) :: general_init

    procedure, pass(this) :: setupField
    procedure, pass(this) :: random_seed_field
    procedure, pass(this) :: single_random_seed_field
    procedure, nopass :: compare_fields
    procedure, pass(this) :: reset_fields

    procedure, pass(this) :: export_image_array
    procedure, nopass :: print_logical_array
    procedure, pass(this) :: write_info_file
    procedure, pass(this) :: print_and_export_each_step

    procedure, pass(this) :: save_rule
    procedure, pass(this) :: open_rule

    procedure, pass(this) :: run
    procedure, pass(this) :: field_iteration
    procedure, pass(this) :: get_last_pattern
    procedure, pass(this) :: reset_to_last_start

end type cell_autom

! A general Moore automaton
type, extends(cell_autom) :: moore_autom

    contains

    procedure, pass(this) :: field_iteration => moore_iteration

end type

contains

! Constructor for moore_autom
function init_moore_autom(M, N, T_steps) result(inst)
    implicit none

    type(moore_autom) :: inst
    type(rule) :: moore_rule
    integer, intent(in) :: M, N, T_steps

    call inst%general_init(M, N, T_steps)

    call moore_rule%init_moore()
    allocate(inst%rule, source = moore_rule)

end function init_moore_autom

0 个答案:

没有答案