When I compile the following Fortran code with gfortran and run it, it gives me 'signal SIGBUS: Access to undefined portion of a memory object', whenever n>=180. I'm running this on a Mac OSX Mavericks.
PROGRAM almatrix
IMPLICIT NONE
INTEGER :: i,j,n
REAL,ALLOCATABLE :: a(:,:)
READ(*,*)n
ALLOCATE(a(n+1,n+1))
DO i=0,n
DO j=0,n
a(i,j)=0.0
END DO
END DO
DEALLOCATE(a)
END PROGRAM almatrix
I understood that instead of
ALLOCATE(a(n+1,n+1))
this
ALLOCATE(a(n+1,n+1),STAT=err)
IF(err /= 0) STOP
would prevent crashing. It didn't, however. Why?
I tried to look at similar problems, but so far they haven't helped.
I tried to compile with -Wall, -g, -fcheck=all, as suggested in another answer, but those didn't give me warnings.
I've also noticed before, that unlike with C, Fortran usually does not give bus errors when using small dynamic arrays and not deallocating them.
The problem isn't directly with the allocate statement, but with accessing the resulting array. [Note also that that an array 181x181 is not "large".] As there is nothing wrong with the allocation, err will indeed be zero.
From that allocate one is left with an array a which has elements a(1,1), a(2,1), ..., a(n+1,1), ..., a(n+1,n+1). So, a(0,0) (the first access in the loop) is not valid.
There are two options: request that the array elements be a(0,0) to a(n,n) as the loop wants, or change the loop:
allocate(a(0:n,0:n))
or
do i=1,n+1
do j=1,n+1
a(j,i) = 0 ! Note I've changed the order to Fortran-friendly
end od
end do
Finally, those loops aren't even necessary:
allocate(a(0:n,0:n))
a = 0.
or even
allocate(a(0:n,0:n), source=0.)
if you have a compiler later than Fortran 95.
Related
I am running a model which is written in Fortan (an executable), in some runs it started to deliver constant errors and apparently incoherent results, however when I closely checked the results file (a text with n columns of data) and I realized that when the concentration of certain mineral is very very low, lets say 2.9984199E-306, the code omits the 'E' and the number presented is 2.9984199-306 which of course causes problems. Since I have no access to the source code of the executable file, is there a way to avoid this problem in Windows? I have seen that in other computers these numbers are directly replaced by zero, however I was not able to find the specific configuration to achieve it.
You will need access to code to change the output formatting or you will need to post-process your output. You are seeing standard conforming Fortran behavior. Consider the simple program
program foo
implicit none
real(8) x
integer i
x = 1
do i = 1, 10
x = x / 5.4321e11
write(*,'(ES15.7)') x
end do
end program foo
It's output is
1.8409086E-12
3.3889446E-24
6.2387373E-36
1.1484945E-47
2.1142735E-59
3.8921843E-71
7.1651557E-83
1.3190397E-94
2.4282316-106
4.4701525-118
See Fortran 2018 Standard, 13.7.2.3.3 E and D editing, in particular, Table 13.1.
I can't debug one of my programs for a year now. When I press the green Run button, the following error message appears:
The full text is:
The GDB command:
"-exec-run"
returned the error:
",msg="Error creating process C:/Users/leven/OneDrive/J\341t\351kpogramok/People/people.exe, (error 193).""
I've read many forums about this error, but my case looks a bit different...
As you can see, the file's path doesn't include any characters that could occur this problem (no spaces, no special letters). I've tried running outside OneDrive, same error.
I've spent a lot of time looking for something in my program that occurs this error and found that if I delete some parts of it (eg. a few procedures or functions, which contains a lot of code though), the program is debuggable again! So the trouble is with some parts of the program, but I still don't know the exact problem.
As I can remember, I've always debugged this program in a 64bit OP.
The one thing that could be problematic is that I probably started writing the program using Windows 7 or 8, and now I want to run it using Windows 10, but I still don't understand, why deleting some parts of the program is a solution...
Thanks in advance for your help!
UPDATE:
I've found, that the line
p[x,y,2,1]:=r;
cannot be debugged by the compiler.
Description:
p: array [1..15000, 1..10000, 1..7, 1..4] of integer;
p[] is a game field. The first two parameters are coordinates, the third and the fourth are not important.
x, y and r are integers.
So, the command seen above writes a number into the game field (p[]) array using the x, y coordinates.
I think we established through a series of queries in comments that the necessary and sufficient condition to provoke the debugger problem you've been getting is to include in your app the declaration of the array p that you've added to your q, that is:
var
p: array [1..15000, 1..10000, 1..7, 1..4] of integer;
For you, it seems that just including this declaration in your code is sufficient to make the debugger throw the error you quote.
For me the debugger starts fine but I get a SIGSEGV error on the assignment to p[] in the following code:
var
p: array [1..15000, 1..10000, 1..7, 1..4] of integer;
x,
y,
r : integer;
begin
x := 100;
y := 100;
r := 666;
p[x, y, 1, 1] := r;
writeln('Press any key ...');
readln;
end.
So, I would try smaller values for the first two bounds of the p array. If that works and you still need the original bounds, I would suggest looking for an FPC library which implements "sparse arrays" and declare p as one of those.
Good luck!
I have a subroutine called several times in an if-then-goto loop.The subroutine has two input arguments:
1.is a constant
2.is an array of definite size(i.e 200X1) whose elements change in a do loop right before the subroutine is called.
The problem is that subroutine doesn't understand that change and returns the same results every time it is called (i.e the results of the first time that it is called).It seems as if the values of all variables that are calculated inside the sudroutine are somehow saved and do not change although input atgument no.2 changes..
Is something wrong with my code?Is there a Fortran bug i'm not aware of?
My code looks like this:
PROGRAM calcul.f
REAL aa(100000),dd(100000),mm(100000),yy(100000),hh(100000),mn(100000),ss(100000),ml(100000),m0(100000)
INTEGER N,snv
DOUBLE PRECISION m0(100000),excerpt(1000),k1(100000),sqsum,s2,vk1,mk1,sdk1,v
filelength=610
W=200
OPEN (1,file='filename.dat')
DO i=1,filelength
READ (1,*) aa(i),dd(i),mm(i),yy(i),hh(i),mn(i),ss(i),ml(i),m0(i)
END D0
CLOSE (1)
10 FORMAT(g12.6)
11 FORMAT(I5,1x,g12.6)
c1=1
c2=W
snv=0
14 IF ((c2.LT.filelength).AND.(c1.LT.(filelength-(W-1)))) THEN
DO i=c1,c2
excerpt(i)=m0(i)
END DO
CALL calk1(W,excerpt)
OPEN (3,file='meank1.dat')
READ (3,*) N,mk1
OPEN (2,file='resultsk1.dat')
DO i=1,N
READ (2,*) k1(i)
END DO
sqsum=0.0d0
DO i=1,N
sqsum=dble(sqsum+((k1(i)-mk1)**2))
s2=sqsum
END DO
vk1=(s2)/N
sdk1=dsqrt(vk1)
OPEN (4,file='resultsv.dat')
v=dble(sdk1/mk1)
snv=snv+1
WRITE (4,11) snv,v
CLOSE (2)
CLOSE (3)
mk1=0.0d0
vk1=0.0d0
sdk1=0.0d0
v=0.0d0
c1=c1+1
c2=c2+1
GOTO 14
END IF
CLOSE (4)
END
My subroutine is:
SUBROUTINE calk1(winlength,sm)
DOUBLE PRECISION sm(100000),sumk1,sum,s,x,x2,k1,sk1,mk1
INTEGER snk1
OPEN (2,file='resultsk1.dat')
10 FORMAT (g12.6)
start=1
w=winlength
c3=6
snk1=0
sumk1=0.0d0
sk1=0.0d0
13 IF (c3.LE.w) THEN
l1=1
l2=c3
c=c3
12 IF ((l1.LE.(w-5)).AND.(l2.LE.w)) THEN
sum=0.0d0
s=0.0d0
DO k=l1,l2
sum=sum+sm(k)
s=sum
END DO
av=0.0d0
av2=0.0d0
x=0.0d0
x2=0.0d0
DO k=l1,l2
av=av+dble(((k)/(c))*(sm(k)/s))
av2=av2+dble((((k)/(c))**2)*(sm(k)/s))
x=av
x2=av2
END DO
k1=x2-((x)**2)
sumk1=sumk1+k1
snk1=snk1+1
WRITE (2,10) k1
l1=l1+1
l2=l2+1
k1=0.0d0
GOTO 12
ELSE
c3=c3+1
GOTO 13
END IF
END IF
CLOSE (2)
N=snk1
sk1=sumk1
mk1=dble((sk1)/N)
OPEN (3,file='meank1.dat')
WRITE (3,10) N,mk1
CLOSE (3)
RETURN
END
I haven't attempted to compile the code (I see there are still some errors that would upset a compiler), but I can suggest a problem.
However, the first thing to say is: if this is your code you'll make things much easier for yourself if you use much more modern Fortran features.
You say that excerpt changes each time before the subroutine is entered. This is true, but not in a meaningful way. Let's look at what is happening to the array.
This is all looped:
c1=1
c2=W
DO i=c1,c2
excerpt(i)=m0(i)
END DO
CALL calk1(W,excerpt)
c1=c1+1
c2=c2+1
Well, W isn't changed in an interation. In this first iteration you are (using array syntax) setting excerpt(1:W)=m0(1:W); in the second setting excerpt(2:W+1)=m0(2:W+1), and so on. That is: each time you call calk1, excerpt(1:W) is still exactly m0(1:W) which hasn't changed. The only change to excerpt is after the W-th element, which you suggest won't be used in the subroutine anyway.
As to what you should do instead with that excerpt setting loop, I can't say: it depends on what you want to happen. Perhaps
DO i=c1,c2
excerpt(i-c1+1) = m0(i)
END DO
?
But use modern Fortran instead.
When I try to compile this I get numerous compiler warnings and errors. I suggest using maximum compile-time warning options from our compiler and clean up those problems. That will clear out some problems with minimal effort. With gfortran, try -O2 -ffixed-form -ffixed-line-length-none -W -Wall -pedantic -fimplicit-none -Wsurprising -Waliasing -Wimplicit-interface -Wunused-parameter -fcheck=all -pedantic -fbacktrace.
Indenting your code with help you understand it. And why use FORTRAN 77 in 2014? Fortran 95/2003 is much easier to program in.
As the title says I'm curious about the difference between "call-by-reference" and "call-by-value-return". I've read about it in some literature, and tried to find additional information on the internet, but I've only found comparison of "call-by-value" and "call-by-reference".
I do understand the difference at memory level, but not at the "conceptual" level, between the two.
The called subroutine will have it's own copy of the actual parameter value to work with, but will, when it ends executing, copy the new local value (bound to the formal parameter) back to the actual parameter of the caller.
When is call-by-value-return actually to prefer above "call-by-reference"? Any example scenario? All I can see is that it takes extra memory and execution time due to the copying of values in the memory-cells.
As a side question, is "call-by-value-return" implemented in 'modern' languages?
Call-by-value-return, from Wikipedia:
This variant has gained attention in multiprocessing contexts and Remote procedure call: if a parameter to a function call is a reference that might be accessible by another thread of execution, its contents may be copied to a new reference that is not; when the function call returns, the updated contents of this new reference are copied back to the original reference ("restored").
So, in more practical terms, it's entirely possible that a variable is in some undesired state in the middle of the execution of a function. With parallel processing this is a problem, since you can attempt to access the variable while it has this value. Copying it to a temporary value avoids this problem.
As an example:
policeCount = 0
everyTimeSomeoneApproachesOrLeaves()
calculatePoliceCount(policeCount)
calculatePoliceCount(count)
count = 0
for each police official
count++
goAboutMyDay()
if policeCount == 0
doSomethingIllegal()
else
doSomethingElse()
Assume everyTimeSomeoneApproachesOrLeaves and goAboutMyDay are executed in parallel.
So if you pass by reference, you could end up getting policeCount right after it was set to 0 in calculatePoliceCount, even if there are police officials around, then you'd end up doing something illegal and probably going to jail, or at least coughing up some money for a bribe. If you pass by value return, this won't happen.
Supported languages?
In my search, I found that Ada and Fortran support this. I don't know of others.
Suppose you have a call by reference function (in C++):
void foobar(int &x, int &y) {
while (y-->0) {
x++;
}
}
and you call it thusly:
int z = 5;
foobar(z, z);
It will never terminate, because x and y are the same reference, each time you decrement y, that is subsequently undone by the increment of x (since they are both really z under the hood).
By contrast using call-by-value-return (in rusty Fortran):
subroutine foobar(x,y):
integer, intent(inout) :: x,y
do while y > 0:
y = y - 1
x = x + 1
end do
end subroutine foobar
If you call this routine with the same variable:
integer, z = 5
call foobar(z,z)
it will still terminate, and at the end z will be changed have a value of either 10 or 0, depending on which result is applied first (I don't remember if a particular order is required and I can't find any quick answers to the question online).
Kindly go to the following link , the program in there can give u an practical idea regarding these two .
Difference between call-by-reference and call-by-value
I do not understand why the following program segfaults with a SIGSEGV if the bar field is present in containerType, and works without problems if it is commented out. I'm on x86_64, compiling with both gfortran-4.4.6 and gfortran-4.6.3.
As I understand it, using a pointer to containerType should force the allocation of the contained big array to happen on the heap but that doesn't seem to be the case. Running valgrind on the executable gives me
Warning: client switching stacks? SP change: 0x7ff000448 --> 0x7fe0603f8
to suppress, use: --max-stackframe=16384080 or greater
(The rest of the output is IMHO not relevant, but I could edit it in if required). This indicates to me that there's a stack overflow; presumably due to allocating the 8*8*8*4000 * 8(bytes per real) = 16384000 bytes on the stack.
When I comment out the bar field, valgrind is perfectly happy. To make matters even stranger, compiling under gfortran-4.6.3 with '-O' also makes the problem go away (but not under gfortran-4.4.6).
Either I've stumbled on a compiler bug, or (more likely, as I'm pretty new to Fortran) I don't understand where data is allocated. Could someone enlighten me what's going on?
The code in question:
main.f90:
program main
use problematicArray
implicit none
type (containerType),pointer :: container
allocate(container)
container%foo%arrayData = 17.0
write(*,*) container%foo%arrayData(7,7,7,100)
deallocate(container)
write(*,*) 'Program finished'
end program main
problematicArray.f90:
module problematicArray
implicit none
private
integer, parameter, public :: dim1 = 4000
type, public :: typeWith4DArray
real(8), dimension(8,8,8,dim1) :: arrayData
end type typeWith4DArray
type :: typeWithChars
character(4), dimension(:), allocatable :: charData
end type typeWithChars
type, public :: containerType
type(typeWith4DArray) :: foo
type(typeWithChars) :: bar
end type containerType
end module problematicArray
This must be a bug in gfortran. I do not see anything wrong there. It also works in Intel and Oracle compilers. Best to report it to gfortran developers. I tried it with only a 2 days old build of the gfortran 4.8 trunk.
The error has nothing to do with stack/heap difference. It simply crashes during the allocate statement. It does not even work with stat= and errmsg= set.
Just a note, you can have the module and the main program inside a single source file.