【问题标题】:Segmentation fault in the script for opening MAT-file打开 MAT 文件的脚本中出现分段错误
【发布时间】:2015-07-24 13:53:15
【问题描述】:

我想在 fortran 中打开一个 MAT 文件,我按照example file 操作。编译和链接发生时没有任何错误或警告。

这是生成文件:

FC = gfortran
FCFLAGS = -g -fcheck=all -Wall
INCLUDES = -I/usr/local/matlab2008a/extern/include
LFLAGS = -L/usr/local/matlab2008a/bin/glnxa64
LIBS = -lmat -lmx
LDFLAGS = "-Wl,-rpath,/usr/local/matlab2008a/bin/glnxa64"

main: main.o param.o dmotifs.o ssa.o
    $(FC) $(LFLAGS) $(LIBS) $(LDFLAGS) -o main main.o param.o dmotifs.o ssa.o  
param.o: param.f90
    $(FC) $(FCFLAGS) -c $<    
dmotifs.o: dmotifs.f90 param.o
    $(FC) $(FCFLAGS) -c $<    
ssa.o: ssa.f90 dmotifs.o
    $(FC) $(FCFLAGS) -c $<   
main.o: main.f90 param.o dmotifs.o ssa.o
    $(FC) -c -cpp $(FCFLAGS) $(INCLUDES) $<    
clean:
    rm -f *.o *.mod *.MOD

但是,当我运行脚本时,出现分段错误错误。

Program received signal SIGSEGV: Segmentation fault - invalid memory reference.

Backtrace for this error:
#0  0x37B4C19497
#1  0x37B4C19ADE
#2  0x37B1E358EF
#3  0x7F1EA50EA7C1
#4  0x401A69 in MAIN__ at main.f90:75
Segmentation fault

这是主要代码:

#include "fintrf.h"

PROGRAM main     
USE ssa
IMPLICIT NONE

CHARACTER(LEN=6) :: argfun
TYPE(fhandle), DIMENSION(13) :: fmotifs
TYPE(funnames), DIMENSION(13) :: fnames
TYPE(PRM) p
REAL, DIMENSION(4) :: y0
REAL tf
REAL, ALLOCATABLE, DIMENSION(:) :: t
REAL, ALLOCATABLE, DIMENSION(:,:) :: y
TYPE(OPTIONS) opt
INTEGER fin
REAL nM2m

! MAT-FILE Declarations !

INTEGER*8 matOpen, matGetDir !, matGetNextVariable
INTEGER matGetVariableInfo
INTEGER mp, dir, adir(100), pa
INTEGER mxGetM, mxGetN, matClose
INTEGER ndir, i, clstat
CHARACTER*32 names(100) !, name

!===========================!


nM2m=1.355178815844751e3;

opt%numsample=2000
tf=1000000

call get_command_argument(1,argfun)

call makemotifs(fnames,fmotifs)
call getparamdef(p)

if(all(fnames(:)%fn .NE. argfun)) then
    write(*,*) "No such motif: ",argfun
    write(*,*) "Input format-> main <motifname>"
    stop
else


    fin=fchton(argfun)  
    y0=nint(nM2m*analys(p,argfun))


    !*** ==> OPEN MAT-file <== ***!

    mp=matOpen('./PRMS_lxr_29Apr15.mat','r')

    if (mp .eq. 0) then
         write(6,*) "Can't open MAT-file"
         stop
    end if

    dir = matgetdir(mp, ndir)

    if (dir .eq. 0) then
         write(6,*) "Can't read MAT-file-directory."
         stop
    endif

    call mxCopyPtrToPtrArray(dir, adir, ndir)

    do 20 i=1,ndir
         call mxCopyPtrToCharacter(adir(i), names(i), 32)
 20 continue

    write(6,*) 'Directory of Mat-file:'

    do 30 i=1,ndir
        write(6,*) names(i)
 30 continue

    write(6,*) 'Getting Header info from first array.'
    pa = matGetVariableInfo(mp, names(1))
    write(6,*) 'Retrieved ', names(1)
    write(6,*) '  With size ', mxGetM(pa), '-by-', mxGetN(pa)
    call mxDestroyArray(pa)

    clstat=matClose(mp)

    call gillespie(fmotifs(fin),y0,p,tf,opt,t,y)

end if

第 75 行(如错误消息中指出的那样):dir = matgetdir(mp, ndir)

我不知道如何解决这个问题。如果我注释掉 MAT 文件的打开部分,那么一切正常。 MAT 文件包含一个浮点 3D 数组 (9x5x10000) 和两个标量。

编辑

似乎对于 64 位系统,指针必须声明为 integer*8 而不是 integer。当我这样做时,我再次在这一行遇到分段错误:
call mxCopyPtrToPtrArray(dir, adir, ndir)

关于这个主题的 Mathworks 文档几乎没有,它们使它看起来是一项非常简单的日常工作。地球上有没有人实际上在 fortran 上打开了一个 MAT 文件?有人可以分享他们的脚本吗?

【问题讨论】:

  • @AlexanderVogt 他有一些回溯,第 75 行。
  • 再次检查您正确调用了 mat* 例程,例如,参数的数量及其类型。如果他们有一些带有显式接口的模块,那将是最好的。
  • 实际上我正在放弃使用 MAT 文件。使用 HDF5 是一个更好的选择。出于一般兴趣保留此帖子。
  • 今天的 MAT 文件是 HDF5 文件的受限形式。如果不查看实际代码,很难在以后的编辑中诊断问题。
  • @IanH 这是实际代码。程序中使用的模块只有用于进行一些计算的子程序。即使我删除了需要这些模块的语句,也会发生此错误。

标签: matlab fortran mat-file


【解决方案1】:

从错误消息中的地址长度来看,您使用的是 64 位系统。

您已将大多数 mat* 函数的结果声明并存储在默认整数中。这可能只是 32 位类型。 mat* 函数实际上返回一个机器指针,在 64 位机器上是 64 位。

您链接到的示例代码可能假定为 32 位平台。

调整您对 mat* 函数的声明以及分配给适当调用这些函数的结果的变量。可能是INTEGER(C_INTPTR_T),其中 C_INTPTR_T 来自 ISO_C_BINDING。

mathworks 提供了一种古老的 C 预处理器方法来指定相关类型(例如,matOpen 的返回类型是 mwPointer),预处理将其更改为适当的整数类型。我个人更喜欢使用自己的接口,使用 Fortran 2003 的 C 互操作性特性编写。

【讨论】:

  • example 中指向注释“在 DEC Alpha 64 位平台上将整数替换为整数 *8”也可能很有用,因为它似乎建议了哪些变量/函数在声明部分进行更改。
  • 谢谢。在将 integer 替换为 integer*8 用于指针声明后,我仍然在第 82 行遇到分段错误:call mxCopyPtrToPtrArray(dir, adir, ndir)
猜你喜欢
  • 2019-05-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-02
  • 1970-01-01
  • 2020-12-31
相关资源
最近更新 更多