Ошибка сегментации в скрипте для открытия MAT-файла

Я хочу открыть MAT-файл в Фортране, и я последовал примеру файла. Компиляция и компоновка происходят без каких-либо ошибок или предупреждений.

Это make-файл:

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 по этой теме - почти ничего, и они делают ее довольно простой рутинной работой. Есть ли кто-нибудь на земле, кто действительно открыл файл MAT на Фортране? Может кто-нибудь поделиться своими сценариями?

1 ответ

Судя по длине адресов в сообщении об ошибке, похоже, что вы работаете в 64-битной системе.

Вы объявили и сохраняете результаты большинства функций mat* в целом числе по умолчанию. Это, вероятно, только 32-битный тип. Функции mat* на самом деле возвращают указатель компьютера, который будет 64-разрядным на 64-разрядном компьютере.

Пример кода, на который вы ссылаетесь, вероятно, предполагает 32-битную платформу.

Настройте ваши объявления для функций mat* и переменных, которым присваиваются результаты правильного вызова этих функций. возможно INTEGER(C_INTPTR_T)где C_INTPTR_T из ISO_C_BINDING.

MathWorks предоставляет архаичные средства препроцессора C для указания соответствующего типа (например, возвращаемый тип matOpen - mwPointer), который преобразуется в соответствующий целочисленный тип. Лично я предпочитаю использовать свои собственные интерфейсы, написанные с использованием функций взаимодействия C в Fortran 2003.

Другие вопросы по тегам