Неправильные значения в подпрограмме Fortran, вызванной из переполнения стека

Я пытаюсь вызвать подпрограмму Fortran из C ++. В качестве справки у меня есть тестовая программа на Фортране, вызывающая ту же подпрограмму, которая дает правильные значения для процедуры. У меня чрезвычайно ограниченные знания Фортрана, поэтому я не могу понять, почему я получаю значения мусора.

Код Фортрана выглядит следующим образом:

program test_9j

implicit none

integer :: ll1, ll2, ll3, ll4, ll5, ll6, ll7, ll8, llmin, llmax, ndim, ier, i

real(8) :: L1, L2, L3, L4, L5, L6, L7, L8, LMIN, LMAX

real(8), allocatable, dimension(:) :: ninecof

ll1 = 2
ll2 = 2
ll3 = 2
ll4 = 2
ll5 = 2
ll6 = 2
ll7 = 2
ll8 = 2

llmin = 0
llmax = 6

print*, llmin, llmax, llmax-llmin+1
print*, ""
L1 = real(ll1,kind=8)
L2 = real(ll2,kind=8)
L3 = real(ll3,kind=8)
L4 = real(ll4,kind=8)
L5 = real(ll5,kind=8)
L6 = real(ll6,kind=8)
L7 = real(ll7,kind=8)
L8 = real(ll8,kind=8)

LMIN = real(llmin,kind=8)
LMAX = real(llmax,kind=8)

ndim = llmax - llmin + 1

ALLOCATE(ninecof(ndim),stat=ier)

!  print*, ier

ninecof = 0.0

print*, "main Hi1"
!  print*, "LL", LMIN, LMAX
CALL w9j(ll1,ll2,ll3,ll4,ll5,ll6,ll7,ll8,llmin,llmax,ndim,ninecof)

!  print*, "main Hi2"
do i=1,ndim
print*, ninecof(i)
end do

print*, "main Hi3a"
!DEALLOCATE(ninecof)

print*, "main Hi3b"
end program test_9j

Это дает серию правильных выходных данных для подпрограммы. Однако когда я пытаюсь сделать это в C ++, это не работает: (примечание: подпрограмма w9j вызывает подпрограмму drc6j, поэтому я включил ее в определение extern. Подпрограмма drc6j выдает правильные результаты.)

using namespace std;

extern "C"{
double drc6j_ (double*, double*, double*, double*, double*,
double*, double*, double*, int*, int*);

double w9j_ (int*, int*, int*, int*, int*,
int*, int*, int*, int*, int*, int*, double*);

}
int main()
{
int N = 1000;
double* coef9j;
int L1, L2, L3, L4, L5, L6, L7, L8, L9, Lmin=0, Lmax=6;

coef9j = new double [ N ];
L1 = 2, L2 = 2, L3 = 2, L4 = 2, L5 = 2, L6 = 2, L7 = 2, L8 = 2;

w9j_ ( &L2, &L3, &L4, &L5, &L6, &L7, &L8, &L9, &Lmin, &Lmax, &N, coef9j );

cout<<" Lmin, Lmax, ierr = "<<Lmin<<","<<Lmax<<","<<ier<<endl;

for (int i=0;i<Lmax-Lmin+1;i++)
cout<<"coeff = "<<setprecision(7)<<coef9j[i]<<endl;

return 0;

}

Эта программа дает значения для Lmin и Lmax, такие как E-315 и т. Д., Что невозможно, потому что я должен получить целочисленные значения, и это тоже ненулевые значения для Lmax. В более ранних подпрограммах (например, drc6j) значения для Lmin и Lmax определялись подпрограммой, и когда я проходил по ссылке, я использовал эти значения. Кроме того, это всегда дает coeff =0 в качестве вывода независимо от входных значений Li.

Пожалуйста, укажите в комментариях, если вы хотите, чтобы подпрограмма drc6j и код C ++ я использовал для ее оценки. Я отредактирую вопрос соответственно.

Выводы, которые я получаю для кода C ++:

AA           2           2           2           2           2           2           2         256           0           6        1000
L9min, L9max, ierr = 0,6,0
coeff = 0
coeff = 0
coeff = 0
coeff = 0
coeff = 0
coeff = 0

И для кода Фортрана:

           0           6           7

main Hi1
-8.5714285714285719E-003
1.7347234759768071E-018
1.6734693877551020E-002
1.7347234759768071E-018
1.3877551020408163E-002
0.0000000000000000
0.0000000000000000
main Hi3a
main Hi3b

Это код подпрограммы w9j:

subroutine w9j(l1,l2,l3,l4,l5,l6,l7,l8,lmin,lmax,ndim,cof9j)

implicit none

!--- in/out variables

integer, intent(in) :: l1, l2, l3, l4, l5, l6, l7, l8, lmin, lmax, ndim
real(8), dimension(ndim), intent(out) :: cof9j

!--- program variables

integer :: l1min, l1max, l2min, l2max, l3min, l3max
integer :: i, j, k, jmin, jmax, ier, dim1, dim2, dim3

real(8) :: y
real(8), allocatable, dimension(:) :: sixj1, sixj2, sixj3
real(8) :: rl1, rl2, rl3, rl4, rl5, rl6, rl7, rl8, ri
real(8) :: rl1min, rl1max, rl2min, rl2max, rl3min, rl3max

!--- --- ---

print*, 'AA', l1,l2,l3,l4,l5,l6,l7,l8,lmin,lmax,ndim

cof9j = 0.0

do k=1,ndim
i=k+lmin-1

!    print*, 'i', i
!    print*, ""
if((l2+i-l1 < 0)  .or. (l2-i+l1 < 0)  .or. (-l2+i+l1 < 0)  .or. &
& (l2+l5-l8 < 0) .or. (l2-l5+l8 < 0) .or. (-l2+l5+l8 < 0) .or. &
& (l4+l3-l5 < 0) .or. (l4-l3+l5 < 0) .or. (-l4+l3+l5 < 0) .or. &
& (l4+l1-l7 < 0) .or. (l4-l1+l7 < 0) .or. (-l4+l1+l7 < 0) .or. &
& (l6+i-l3 < 0)  .or. (l6-i+l3 < 0)  .or. (-l6+i+l3 < 0)  .or. &
& (l6+l7-l8 < 0) .or. (l6-l7+l8 < 0) .or. (-l6+l7+l8 < 0)) then
!      print*, "violation of triangularity"cof9j(k) = 0.0
cycle
end if

l1min=max(abs(i-l8),abs(l5-l1))
l1max=min(i+l8,l5+l1)
dim1 = l1max -l1min + 1
!    print*, 'l1', l1min,l1max,dim1
!    print*, ""
l2min=max(abs(l3-l7),abs(l1-l5))
l2max=min(l3+l7,l1+l5)
dim2 = l2max -l2min + 1
!    print*, 'l2', l2min,l2max,dim2
!    print*, ""
l3min=max(abs(i-l8),abs(l7-l3))
l3max=min(i+l8,l7+l3)
dim3 = l3max -l3min + 1
!    print*, 'l3', l3min,l3max,dim3
!    print*, ""
if (l1max < l1min .or. l2max < l2min .or. l3max < l3min) then
cof9j(k) = 0.0
cycle
end if

allocate(sixj1(dim1))
allocate(sixj2(dim2))
allocate(sixj3(dim3))

sixj1 = 0.0
sixj2 = 0.0
sixj3 = 0.0

ri  = real(i)  ! L1
rl1 = real(l1) ! L2
rl2 = real(l2) ! L3
rl3 = real(l3) ! L4
rl4 = real(l4) ! L5
rl5 = real(l5) ! L6
rl6 = real(l6) ! L7
rl7 = real(l7) ! L8
rl8 = real(l8) ! L9
rl1min = 0.0
rl1max = 0.0
rl2min = 0.0
rl2max = 0.0
rl2min = 0.0
rl3max = 0.0

!      SUBROUTINE DRC6J (L2, L3, L4, L5, L6, L1MIN, L1MAX, SIXCOF, NDIM, IER)
!          L1MAX=MIN(L2+L3,L5+L6) and L1MIN=MAX(ABS(L2-L3),ABS(L5-L6)).

!    print*, "Hi1"
!    print*, 'BB',ri,rl1,rl2,rl3,rl4,rl5,rl6,rl7,rl8,dim1,dim2,dim3

!              L2  L3  L4  L5  L6
call DRC6J(ri,rl8,rl2,rl5,rl1,rl1min,rl1max,sixj1,dim1,ier)
!    print*, "6j - 1"!              L2  L3  L4  L5  L6
call DRC6J(rl3,rl7,rl4,rl1,rl5,rl2min,rl2max,sixj2,dim2,ier)
!    print*, "6j - 2"!              L2  L3  L4  L5  L6
call DRC6J(ri,rl8,rl6,rl7,rl3,rl3min,rl3max,sixj3,dim3,ier)
!    print*, "6j - 3"
!    print*, "Hi2"
if (l1min /= int(rl1min) .or. l1max /= int(rl1max) .or. &
&   l2min /= int(rl2min) .or. l2max /= int(rl2max) .or. &
&   l3min /= int(rl3min) .or. l3max /= int(rl3max)) then
print*, "Declared dimensions of 'sixj' arrays are wrong"end if

jmin = max(l1min,l2min,l3min)
jmax = min(l1max,l2max,l3max)
print*, 'Jmin Jmax', jmin, jmaxy = 0.0

if(jmin <= jmax) then

do j=jmin,jmax
y = y + (2.0*j+1.0)*sixj1(j-l1min+1)*sixj2(j-l2min+1)*sixj3(j-l3min+1)
end do

end if

cof9j(k) = y

deallocate(sixj1,sixj2,sixj3)

end do
print*, 'end values', l1,l2,l3,l4,l5,l6,l7,l8,lmin,lmax,ndimreturn

end subroutine w9j

Подпрограмму для drc6j.f и зависимостей можно найти на netlib.org

0

Решение

Ни в какой точке w9j Вы устанавливаете lmin а также lmax и ни в одной точке вашего кода C ++ вы не устанавливаете эти переменные, следовательно, когда вы печатаете их в своем коде C ++, вы просто печатаете любое значение, которое было в памяти в месте расположения этих переменных — т.е. оно не определено. В вашем исходном коде Fortran вы устанавливаете эти переменные перед передачей их w9j вот почему это, кажется, работает.

Обратите внимание, что вы отметили Lmin а также Lmax как intent(in) в w9j но затем вы пытаетесь распечатать их в коде C ++, как будто они были выходами w9j, Аргументы отмечены как intent(in) не должны быть изменены в рамках этой процедуры.

Обновить следующие комментарии

Финальным исправлением было отметить, что вызов c ++ w9j не проходит l1 но ты проходишь l9 который ничего не установлен, что приводит к использованию неопределенного значения в основном w9j рутина.

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]