I have the following code.
PROGRAM CTS
implicit none
!C driver for routine fourn
INTEGER NDAT,NDIM
PARAMETER(NDIM=1,NDAT=1024)
INTEGER i,idum,isign,j,k,l,nn(NDIM)
REAL data1(NDAT),data2(NDAT),ran1 ,x,dx
REAL,DIMENSION(:),ALLOCATABLE::F,F1
allocate(F(NDAT),F1(NDAT))
x=1.
dx = (200.-1.)/real(NDAT)
nn(1)=NDAT
do i=1,NDAT
F1(i) =atan(x-100)
x= x + dx
enddo
x=1.
x=1.
isign=1
call fo(F1,nn,1,isign)
open(1,file="zresult.dat",status="replace")
do i=1,NDAT
write(1,*)x,F1(i)*dx
x= x + dx
enddo
stop
END
!!!!!!!!!!!!!!!!!!!!!!!!!!
SUBROUTINE fo(data,nn,ndim,isign)
INTEGER isign,ndim,nn(ndim)
REAL data(*)
INTEGER i1,i2,i2rev,i3,i3rev,ibit,idim,ifp1,ifp2,ip1,ip2,ip3,k1,&
k2,n,nprev,nrem,ntot
REAL tempi,tempr
DOUBLE PRECISION theta,wi,wpi,wpr,wr,wtemp
ntot=1
do 11 idim=1,ndim
ntot=ntot*nn(idim)
11 continue
nprev=1
do 18 idim=1,ndim
n=nn(idim)
nrem=ntot/(n*nprev)
ip1=2*nprev
ip2=ip1*n
ip3=ip2*nrem
i2rev=1
do 14 i2=1,ip2,ip1
if(i2.lt.i2rev)then
do 13 i1=i2,i2+ip1-2,2
do 12 i3=i1,ip3,ip2
i3rev=i2rev+i3-i2
tempr=data(i3)
tempi=data(i3+1)
data(i3)=data(i3rev)
data(i3+1)=data(i3rev+1)
data(i3rev)=tempr
data(i3rev+1)=tempi
12 continue
13 continue
endif
ibit=ip2/2
1 if ((ibit.ge.ip1).and.(i2rev.gt.ibit)) then
i2rev=i2rev-ibit
ibit=ibit/2
goto 1
endif
i2rev=i2rev+ibit
14 continue
ifp1=ip1
2 if(ifp1.lt.ip2)then
ifp2=2*ifp1
theta=isign*6.28318530717959d0/(ifp2/ip1)
wpr=-2.d0*sin(0.5d0*theta)**2
wpi=sin(theta)
wr=1.d0
wi=0.d0
do 17 i3=1,ifp1,ip1
do 16 i1=i3,i3+ip1-2,2
do 15 i2=i1,ip3,ifp2
k1=i2
k2=k1+ifp1
tempr=sngl(wr)*data(k2)-sngl(wi)*data(k2+1)
tempi=sngl(wr)*data(k2+1)+sngl(wi)*data(k2)
data(k2)=data(k1)-tempr
data(k2+1)=data(k1+1)-tempi
data(k1)=data(k1)+tempr
data(k1+1)=data(k1+1)+tempi
15 continue
16 continue
wtemp=wr
wr=wr*wpr-wi*wpi+wr
wi=wi*wpr+wtemp*wpi+wi
17 continue
ifp1=ifp2
goto 2
endif
nprev=n*nprev
18 continue
return
END
!!!!!!!!!!!
The problem is If I do not allocate F1 and put REAL F1(NDAT), the code runs without any problem, but when I allocate F1 I will get the following error
I have tried all possibilities to understand what is happening -fcheck=all etc. it seems memory corruption.
*** Error in `./out': free(): invalid next size (normal): 0x088a7f20 ***
Program received signal SIGABRT: Process abort signal.
Backtrace for this error:
#0 0xB76BE133
#1 0xB76BE7D0
#2 0xB77C73FF
#3 0xB77C7424
#4 0xB74E4686
#5 0xB74E7AB2
#6 0xB751EFD2
#7 0xB75294C9
#8 0xB752A13C
#9 0xB7777607
#10 0xB776EECF
#11 0xB776EFB9
#12 0xB76BDA93
#13 0xB77D733B
#14 0xB74E9230
#15 0xB74E928C
#16 0xB76C09E7
#17 0x80496D4 in cts at z2.f90:33
Aborted (core dumped)
Could you please help me to find out where the problem is.
Thank you so much
If you move the END after the subroutine, put CONTAINS before the subroutine to make it internal the program, change assumed size array
data(*)
to assumed shape array
data(:)
(just using data(NDAT) would also help)
then you can compile your code as
gfortran-7 -Wall -Wno-unused-variable -fcheck=all memcorr.f90
and get clear message
> ./a.out
At line 63 of file memcorr.f90
Fortran runtime error: Index '1025' of dimension 1 of array 'data' above upper bound of 1024
That means your are accessing your array out of bounds.
Line 63 is:
data(i3)=data(i3rev)
so i3 or i3rev is too large (larger than NDAT). You must find out why and fix that.
The point is: use explicit interfaces, assumed shape arrays and all other Fortran 90 stuff that will help you find bugs.
The best thing is to use modules for all your subroutines and functions.
Related
The following code produces a memory error when compiled with recent versions of gfortran (10.3 or later):
module distributed_array
implicit none
type :: darray_segment
integer::rank
integer::offset
integer::length
real(kind=8), allocatable::data(:)
contains
end type darray_segment
type :: darray
type(darray_segment), allocatable::segments(:)
end type darray
contains
function new_darray(segments)
class(darray_segment), intent(in)::segments(:)
type(darray)::new_darray
new_darray%segments = segments
end function new_darray
end module distributed_array
program test_darray
use distributed_array, ONLY: darray, darray_segment, new_darray
implicit none
integer, parameter::np_src = 4
integer, parameter::np_dest = 3
type(darray)::src_darray
type(darray)::dest_darray
type(darray_segment)::src_segments(np_src)
type(darray_segment)::dest_segments(np_dest)
src_darray = new_darray(src_segments)
dest_darray = new_darray(dest_segments)
end program test_darray
The output produced is as follows:
darray_test: malloc.c:2385: sysmalloc: Assertion `(old_top == initial_top (av) && old_size == 0) || ((unsigned long) (old_size) >= MINSIZE && prev_inuse (old_top) && ((unsigned long) old_end & (pagesize - 1)) == 0)' failed.
Program received signal SIGABRT: Process abort signal.
Backtrace for this error:
#0 0x7f727c59fbf0 in ???
#1 0x7f727c59ee45 in ???
#2 0x7f727c20d83f in ???
at /build/glibc-vjB4T1/glibc-2.28/signal/../sysdeps/unix/sysv/linux/x86_64/sigaction.c:0
#3 0x7f727c20d7bb in __GI_raise
at ../sysdeps/unix/sysv/linux/raise.c:51
#4 0x7f727c1f8534 in __GI_abort
at /build/glibc-vjB4T1/glibc-2.28/stdlib/abort.c:79
#5 0x7f727c255a67 in __malloc_assert
at /build/glibc-vjB4T1/glibc-2.28/malloc/malloc.c:298
#6 0x7f727c257e6e in sysmalloc
at /build/glibc-vjB4T1/glibc-2.28/malloc/malloc.c:2382
#7 0x7f727c2592c8 in _int_malloc
at /build/glibc-vjB4T1/glibc-2.28/malloc/malloc.c:4133
#8 0x7f727c25a3e2 in __GI___libc_malloc
at /build/glibc-vjB4T1/glibc-2.28/malloc/malloc.c:3049
#9 0x401f10 in __distributed_array_MOD_new_darray
at /test/src/test/darray_tests.F90:23
#10 0x402933 in test_darray
at /test/src/test/darray_tests.F90:44
#11 0x402aaf in main
at /test/src/test/darray_tests.F90:31
The code runs without error when compiled with gfortran 4.9.4 and 10.2, but the above error occurs with versions 10.3 and 11.
The problem appears to be related to the assignment operation new_darray%segments = segments. If I declare segments as type(darray_segment) instead of class(darray_segment), then the program no longer crashes. So apparently the problem is triggered by assignment from a polymorphic variable. Is such assignment supposed to be allowed per the Fortran standard?
I get this problem since there are more number of lines (ndt=112256), whereas, when the number of lines are less (say, if ndt=69888), it works fine.
I tried increasing the maximum limit in the first few lines of the code
real dt,crad,p
dimension dt(9000000),crad(9000000),p(1000)
dimension a(90000000)
integer rvac
ndt=112256
open (unit=1,file='x.dat')
open (unit=4,file='x1.dat')
do j=1,1000
p(j)=0.0d0
enddo
do i=1,ndt
read(1,*) dt(i), a(i), crad(i)
rvac = crad(i)
if (rvac.le.180)then
p(rvac)=p(rvac)+1
endif
enddo
sum=0.
sum1=0.
do rvac=1,180
write(4,*) rvac,p(rvac),p(rvac)/ndt
c111 format(f12.5,3x,f12.5)
enddo
c
stop
end
I get error as:
"Program received signal SIGSEGV: Segmentation fault - invalid memory reference.
Backtrace for this error:
#0 0x2B76431D4777
#1 0x2B76431D4D7E
#2 0x2B764350BCAF
#3 0x400BA8 in MAIN__ at prob.f:?
Segmentation fault (core dumped)"
Any suggestions are highly appreciated.
I'm currenlty learning modern Fortran, I use the TDM-GCC compiler on Windows 10 64bit.
After compiling correcly my code, I received this message when trying to run the output .exe
Program received signal SIGSEGV: Segmentation fault - invalid memory reference.
Backtrace for this error:
#0 ffffffffffffffff
#1 ffffffffffffffff
#2 ffffffffffffffff
#3 ffffffffffffffff
#4 ffffffffffffffff
#5 ffffffffffffffff
#6 ffffffffffffffff
#7 ffffffffffffffff
#8 ffffffffffffffff
#9 ffffffffffffffff
#10 ffffffffffffffff
#11 ffffffffffffffff
#12 ffffffffffffffff
#13 ffffffffffffffff
#14 ffffffffffffffff
#15 ffffffffffffffff
#16 ffffffffffffffff
#17 ffffffffffffffff
#18 ffffffffffffffff
I understood the problem may be caused by reading I/O files. Here's the code (it's not mine, it's from the course teacher, he told me it's a runtime error, but has no idea why I get the error while reading a file):
program golden_ratio
! experiments with the golden ratio iterative relation
implicit none
integer, parameter :: rk = kind(1.0d0)
real(rk) :: phi, phi_old
real(rk) :: phi_start, tol
integer :: i, max_iter
open(11,FILE='goldenfile.in',STATUS='old')
read(11,*) phi_start, tol, max_iter
close(11)
! how I wrote the input file
! 5.0
! 0.0001
! 1000
phi_old = phi_start
do i=1,max_iter
phi = 1.0d0/phi_old + 1.0d0
if (abs(phi - phi_old) < tol) exit
phi_old = phi
end do
open(12,FILE='goldenfile.out',STATUS='replace')
write(12,100) 'Start value:',phi_start
write(12,100) 'Tolerance:',tol
write(12,'(2(A," ",I11," "))') 'Ended at iteration:', i, 'of', max_iter
write(12,100) 'Final value:',phi
close(12)
print *, 'Output file created'
100 format(A," ",F13.10)
end program golden_ratio
So this problem occurs when I try to open the input file 'goldenfile.in' (which is present in the same directory, defined as I wrote in the commented section, obviously it doesn't contain the comment marks).
It also occurs when I forgo using the input file, and I try to overwrite the output file 'goldenfile.out' after having obtained it a first time. Using 'replace' or not doesn't change the situation.
The strange thing is that the compilation goes right.
I have to allocate memory for 4 pointers to pointers on float (2D) over many iterations (6), but at the second iteration, malloc gives me the same address for two allocations. Code :
int i=0, a=0;
for(i=0;i<6;i++)
{
float** P_i=(float**) malloc(4*sizeof(float*));
for(a=0;a<4;a++) P_i[a]=(float*) calloc(4,sizeof(float));
for(a=0;a<4;a++) free(P_i[a]);
free(P_i);
}
Debugging with gdb :
(gdb) print i
$42 = 1
(gdb) set $pos=0
(gdb) print P_i[$pos++]
$51 = (float *) 0x804d500
(gdb) print P_i[$pos++]
$52 = (float *) 0x804d148
(gdb) print P_i[$pos++]
$53 = (float *) 0x804d4e8
(gdb) print P_i[$pos++]
$54 = (float *) 0x804d500
P_i[0] and P_i[3] point to the same address 0x804d500 and I can't find why :/
between the first for(a=0;a<4;a++) and the 2nd (before freeing)
My guess is that gdb breaks on last iteration of the loop, before the last calloc() call. If it's the case P_i[3] have the address of the previous iteration.
Btw, it's hard to use gdb when there's more than one statement per line.
With information available this can't be answered, but let me try.
The code seems ok. I can't reproduce your problem either.
You can't really put a breakpoint on a blank line. I guess that would put it on a line with free.
My guess is, your code was compiled with optimization enabled, which probably reordered things making sure you are not really sure where execution has stopped. Disable optimization and re-build (on GCC that would be -O0). Or show us the disassembly (including current PC where you print).
My run on Ubuntu gcc (Ubuntu 4.8.4-2ubuntu1~14.04.1) 4.8.4 built with -O0 -g, stopped on a line with free (before it was executed):
(gdb) print i
$1 = 0
(gdb) set $pos=0
(gdb) print P_i[$pos++]
$2 = (float *) 0x602040
(gdb) print P_i[$pos++]
$3 = (float *) 0x602060
(gdb) print P_i[$pos++]
$4 = (float *) 0x602080
(gdb) print P_i[$pos++]
$5 = (float *) 0x6020a0
(gdb) bt
#0 main () at malloc.c:12
(gdb) list
7 for(i=0;i<6;i++)
8 {
9 float** P_i=(float**) malloc(4*sizeof(float*));
10 for(a=0;a<4;a++) P_i[a]=(float*) calloc(4,sizeof(float));
11
12 for(a=0;a<4;a++) free(P_i[a]);
Does your source code exhibit a problem even if you build it separately (not a part of larger program)? Do you have custom calloc / malloc implemented? What does "nm your-executable|grep calloc" show? It should be something like this:
U calloc##GLIBC_2.2.5
I've just started using CGAL to calculate the minkowski sum along a polyline - basically a 'glide' operation. There is a nice example of it here:
http://doc.cgal.org/latest/Minkowski_sum_3/index.html#Minkowski_sum_3Glide
Unfortunately, I run into troubles as soon as some points of the polyline are the equal.
For example for a closed ring:
Point_3 pl[6] =
{Point_3(-100,0,0),
Point_3(40,-70,0),
Point_3(40,50,40),
Point_3(-90,-60,60),
Point_3(0, 0, -100),
Point_3(-100,0,0)
};
It results in
terminate called after throwing an instance of 'CGAL::Assertion_exception'
what(): CGAL ERROR: assertion violation!
Expr: N.is_valid(0,0)
File: /usr/include/CGAL/convex_decomposition_3.h
Line: 141
[1] 30341 done cat cube.nef3 |
30342 abort (core dumped) ./glide
The backtrack looks like this:
0 raise /usr/lib/libc.so.6 0x7ffff693a369
1 abort /usr/lib/libc.so.6 0x7ffff693b768
2 __gnu_cxx::__verbose_terminate_handler() /usr/lib/libstdc++.so.6 0x7ffff7228635
3 ?? /usr/lib/libstdc++.so.6 0x7ffff72267a6
4 std::terminate() /usr/lib/libstdc++.so.6 0x7ffff72267d3
5 __cxa_throw /usr/lib/libstdc++.so.6 0x7ffff72269fe
6 CGAL::assertion_fail(char const*, char const*, int, char const*) /usr/lib/libCGAL.so.10 0x7ffff76f9ee9
7 CGAL::convex_decomposition_3<CGAL::Nef_polyhedron_3<CGAL::Epeck, CGAL::SNC_indexed_items, bool> > convex_decomposition_3.h 141 0x596500
8 CGAL::minkowski_sum_3<CGAL::Nef_polyhedron_3<CGAL::Epeck, CGAL::SNC_indexed_items, bool> > minkowski_sum_3.h 91 0x59c691
9 main glide.cpp 35 0x4cbdfb
Probably, Nef Polyhedra don't allow intersection.
Is there any way out of this? Help is really very much appreciated.
I did ask CGAL developers and they replied that the code does not allow self-intersecting polylines. You need to split your polylines yourself.