For Programmers: Free Programming Magazines  


Home > Archive > Fortran > September 2005 > zero values on dynamic array









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author zero values on dynamic array
kis

2005-09-14, 7:00 pm

Hi all,

Need help.
I have two pieces of code:

First code:

program firstcode
real,allocatable :: a(:)
allocate(a(10))
a=10.
do i=1,20
print*,a(i)
enddo
end program firstcode


Second code:

program secondcode
real a(10)
a=10.
do i=1,20
print*,a(i)
enddo
end program firstcode

For unknown reason, the first code gives a(i) NOT equals to zero for
i>10 and the second code gives a(i) equals to zero for i>10. I compile
the both codes using COMPAQ VISUAL FORTRAN 6.6 with the "Array and
String Bounds" (in Runtime) option UNCHECKED.

Does anybody know how to initialize the dynamic array to zero for out
of bound indices such as above?

Thanks
Irfan

FJRA

2005-09-14, 7:00 pm

I think you should not use your index out of bounds, you can get a
memory access error (try go to 1000 instead of 20, or maybe more to see
how it crash). As far as I know, you are accessing memory outside the
place you have access, and you cannot (must not) change it.

FJRA

glen herrmannsfeldt

2005-09-14, 7:00 pm

kis wrote:

(snip of code using, and not using ALLOCATABLE)

> For unknown reason, the first code gives a(i) NOT equals to zero for
> i>10 and the second code gives a(i) equals to zero for i>10. I compile
> the both codes using COMPAQ VISUAL FORTRAN 6.6 with the "Array and
> String Bounds" (in Runtime) option UNCHECKED.


> Does anybody know how to initialize the dynamic array to zero for out
> of bound indices such as above?


This question doesn't really make sense. You can't initialize out of
bounds data, static or dynamic. How about this, though. Allocate one
extra element on each end, so 0:11, initialize element 0 and 11, then

A(MAX(MIN(I,11),0)) wherever you now have A(I).

-- glen

James Van Buskirk

2005-09-14, 9:57 pm

"kis" <kisitanggang@gmail.com> wrote in message
news:1126740502.852498.86100@g43g2000cwa.googlegroups.com...

> Does anybody know how to initialize the dynamic array to zero for out
> of bound indices such as above?


Please restrict horror to the days immediately surrounding
Halloween.

--
write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, &
6.0134700243160014d-154/),(/'x'/)); end


kis

2005-09-14, 9:57 pm

Hi,

Thanks for all responses.
I am aware that it doesn't make sense. And I personally do not like
that code. But I have a huge hydrodynamic code (13k lines) that was
written sometime ago. This code, as it is, has a lot of lines with that
kind of programming style. Rather than spending too much time on
changing too much on the code, it would be helpful if there is a way to
initialize all variables (including dynamic array) to zeros as required
by the original code.
I believe there is option in Fortran compiler that allows user to
initialize variables to zeros without explicitly code it in the body of
the code.

Thanks, look forward to kind help.

Irfan

Richard Maine

2005-09-14, 9:57 pm

In article <1126740502.852498.86100@g43g2000cwa.googlegroups.com>,
"kis" <kisitanggang@gmail.com> wrote:

> Does anybody know how to initialize the dynamic array to zero for out
> of bound indices such as above?


That makes no sense. The array doesn't exist out of its bounds, so there
isn't anything to initialize. If an out-of-bounds index is not caught,
then invariably what you will get is the memory of *OTHER* things in the
program, not that of the array.

The only way to initialize it to zero for all out-of-bounds indices
would be to initialize every memory location in the program to zero.
Depending on the architecture, this might also include the program
executable code, which wouldn't leave much of an "interesting" program.

Most compilers have options to diagnose the use of out-of-bounds index
values.
Steven G. Kargl

2005-09-14, 9:57 pm

In article <1126745773.329426.213290@f14g2000cwb.googlegroups.com>,
"kis" <kisitanggang@gmail.com> writes:
> I believe there is option in Fortran compiler that allows user to
> initialize variables to zeros without explicitly code it in the body of
> the code.


Yes, many compilers have options to initialize *variables*
to zero. But, what you want isn't initializing a variable.
You would be randomly writing to memory, which is not a
Good Thing. Trying to access array elements beyond its
bounds probably violates a boatload of requirements of the
standard.

--
Steve
http://troutmask.apl.washington.edu/~kargl/
Richard Maine

2005-09-14, 9:57 pm

In article <1126745773.329426.213290@f14g2000cwb.googlegroups.com>,
"kis" <kisitanggang@gmail.com> wrote:

> This code, as it is, has a lot of lines with that
> kind of programming style.


Then either it doesn't work correctly and never did, or you
misunderstand what it is doing.

> if there is a way to
> initialize all variables (including dynamic array) to zeros as required
> by the original code.


No, there isn't. Nor has there ever been in any compiler ever in
existence, nor will there ever be. Not if you are including
out-of-bounds indices as explicitly mentioned in the original post. As
mentioned by me and others, the concept of initializing out-of-bounds
values to zero doesn't even make sense. It isn't a matter of whether
compilers happen to have the option - there isn't such a thing to have.
One might as well wonder whether there is a compiler option to make the
color blue be a rabbit (no, there isn't).

Now if you want an option to initialize all static (not dynamic)
variables to zero, many compilers have that. The details vary from one
compiler to another. I don't offhand know the answer for CVF, but I bet
it has one.

Initializing dynamically allocated memory to zero is also plausible. It
might even be the default for some systems. Again, I don't know
CVF-specific details.

All of the above things are compiler-dependent.

But initializing out-of-bounds data to zero is not compiler dependent,
particularly for dynamically allocated arrays. Let's see. Every time
that any allocation is done, all memory of the entire program is set to
zero? It just does not make sense. If you think that you have a program
that depends on that, then either the program doesn't actually work or
you are mistaken in thinking that it depends on that. There really are
no other possibilities.
kis

2005-09-14, 9:57 pm

Ok, probably I am wrong and probably you are right. But, what about the
second code. This is a static array of size 10. When the index of the
loop go beyond 10 (i.e. 11, 12, ...., etc), what pops up on (print*,
a(i)) the screen are zeros. How could we explain that.

Probably it is not quite right to use the term "initializing". And
probably the best way to illustrate this problem is as follows:

program dumb
real :: a(10), b(20)
a=10.
do i=1,20
b(i)=2.0*a(i)
enddo
end

Rather than writing the code like that it is better writing it as
follows:

program smart
real :: a(10), b(20)
a=10.
do i=1,20
if(i.le.10)then
b(i)=2.0*a(i)
else
b(i)=0.0
endif
enddo
end

Both code will give: b(1:10)=20. and b(11:20)=0.0. Of course, again,
need to uncheck the "Array and String Bounds" option in CVF 6.6 in the
first code.

The author of the hydrodynamic code that I mentioned above used the
first version (without if), which is bad. The code, originally was
written using static arrays. I tried to modify it to allow for dynamic
arrays. Then this problem arose.

Thanks,
Irfan

John Harper

2005-09-14, 9:57 pm

In article <1126745773.329426.213290@f14g2000cwb.googlegroups.com>,
kis <kisitanggang@gmail.com> wrote:
>Hi,
>
>Thanks for all responses.
>I am aware that it doesn't make sense. And I personally do not like
>that code. But I have a huge hydrodynamic code (13k lines) that was
>written sometime ago. This code, as it is, has a lot of lines with that
>kind of programming style.


So why do you trust it? Fortran used to be called the language in which
you get wrong answers fast...

John Harper, School of Mathematics, Statistics and Computer Science,
Victoria University, PO Box 600, Wellington, New Zealand
e-mail john.harper@vuw.ac.nz phone (+64)(4)463 5341 fax (+64)(4)463 5045
Richard Maine

2005-09-15, 3:57 am

In article <1126751739.985145.190060@z14g2000cwz.googlegroups.com>,
"kis" <kisitanggang@gmail.com> wrote:

> The author of the hydrodynamic code that I mentioned above used the
> first version (without if), which is bad. The code, originally was
> written using static arrays. I tried to modify it to allow for dynamic
> arrays. Then this problem arose.


Hmm. Maybe this makes a little more sense now. With static arrays there
are other possibilities. They are often considered "questionable" coding
practices, but they can at least make sense. I suspect that you haven't
told us everything important about the code because you didn't realize
what was important.

As I said before, when you index outside of the array bounds, you are
looking at memory of something else. Well, with dynamic allocation, you
basically don't have any way of knowing or controlling what that
something else is. But with static allocation, there are ways. You can
make sure that you also statically control what other data lies after
the array in question. It occurs to me that this might be what your
original code does. There are several ways to do that.

Perhaps the most common such way is using COMMON. If, for example, your
original code had something like

common /something/ A, AA

and both A and AA were dimensioned 10. Then referencing a(11) through
a(20) will get you the same memory locations as AA.

There are a few other ways to pull tricks like this, but COMMON is the
most widespread one. The worst such way is to assume that you know how
the compiler will happen to lay out static memory. I've seen that done.
I even once did it myself by accident 30 years or so ago. (I had
intended to use that COMMON trick, but accidentally left out the common
statement. But the way I ordered the declarations in the code happened
to cause that particular compiler to lay out memory like I wanted
anyway. I later found this out when I wondered why it didn't work on a
different compiler.)

As I said, the use of COMMON or other tricks to do this is
"questionable" coding style, but it is one that is sometimes used. It at
least makes sense and can work. It doesn't trivially extend to dynamic
allocation because it fundamentally depends on knowing the relationship
of two arrays in memory. That doesn't work to well with independent
dynamic allocation of the 2 arrays. There might be tricks you can play,
though they can get a bit ugly. But first you'd need a good
understanding of what the original code was really doing.
glen herrmannsfeldt

2005-09-15, 3:57 am

kis wrote:

> Ok, probably I am wrong and probably you are right. But, what about the
> second code. This is a static array of size 10. When the index of the
> loop go beyond 10 (i.e. 11, 12, ...., etc), what pops up on (print*,
> a(i)) the screen are zeros. How could we explain that.


Often static arrays will be allocated right next to each other.
Just before or after A is another array.

For dynamic arrays often some part of the system needs to keep
extra information related to the array nearby so they usually
aren't right next to each other. In your simple program there
wasn't another array, so it is harder to say what might be there.
Still, it is slightly more likely to be zero, but there is no way
you can count on it being zero or not zero in any case.

If you really need it, allocate them slightly larger. It is often
faster to make the arrays slightly larger than to put extra tests
in the code.

As a side note, the AWK language specifies that uninitialized
array elements are zero. Array elements are created when referenced,
either read or written. There is a fair amount of overhead to do
that, though. There are no bounds, so you can't ask if an element
is or is not in bounds.

-- glen

kis

2005-09-15, 3:57 am

Thanks for your kind comment. Probably the best that I can do for now
is to isolate all "out of bound arrays" and rewrite them in a more
elegant way. A lot of pain, of course!!!

Thanks a lot
Irfan

e p chandler

2005-09-15, 3:57 am


James Van Buskirk wrote:
> "kis" <kisitanggang@gmail.com> wrote in message
> news:1126740502.852498.86100@g43g2000cwa.googlegroups.com...
>
>
> Please restrict horror to the days immediately surrounding
> Halloween.
>
> --
> write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, &
> 6.0134700243160014d-154/),(/'x'/)); end


Only if the processor supports BTF instructions.

http://foldoc.doc.ic.ac.uk/foldoc/f...nch+to+Fishkill

Jan Vorbrüggen

2005-09-15, 3:57 am

> Ok, probably I am wrong and probably you are right. But, what about the
> second code. This is a static array of size 10. When the index of the
> loop go beyond 10 (i.e. 11, 12, ...., etc), what pops up on (print*,
> a(i)) the screen are zeros. How could we explain that.


Technically, the explanation is that the compiler tells the linker to
allocate 10 items in a part of the program called the data section. Such
a section is at least a page in size in the final, linked program, and is
usually set up to be initialized to zero by the operating system - a so-
called demand-zero page. (It has to be initialized to some value, other-
wise data could leak from the process that had used this physical page
before to your process, and that's strictly forbidden for security reasons.
So one might as well set everything to zero, though setting it to a random
value would sometimes - e.g., in your case - be a Good Thing for purposes
of debugging.)

As it so happens that you have not "touched" the additional memory on the
same page as your array before, you will now get the value 0 for the out-
of-bounds elements of the array - until you reach the end of the page, when
all bets are off: you might then try to access memory that isn't allocated
to you, and will get an exception (segmentation fault or similar), or you
access other data.

In the case of dynamic allocation, it is likely (although not guaranteed)
that other parts of your program (which includes parts you haven't written
yourself but that are included by the compiler to support your program)
have already written to the page that was initialized to zero when your
program was started, and you thus see random values.

While all of this is interesting if arcane, you should really get it into
your head what others have been telling: The code as you now have it is
fundamentally broken. It might, by accident, actually have produced useful
or "correct" results in the past, although I wouldn't bet very much on that.
It certainly is very "brittle", as you have already noticed: a seemingly
small change will make it apparent that it is, indeed, incorrect. Before
you proceed, you really, really need to correct it first.

Jan
andy2O

2005-09-15, 7:57 am

kis wrote:

> Thanks for your kind comment. Probably the best that I can do for now
> is to isolate all "out of bound arrays" and rewrite them in a more
> elegant way. A lot of pain, of course!!!
>
> Thanks a lot
> Irfan


OK... but be very careful, in light of what Richard Maine said!

Perhaps you've caught on to this, but I'll spell it out in great
detail, because if you missed it, and change your code without
understanding, you could be in for a lot of pain!

*IF* your code is using the trick Richard noted, of using elements
A(11) to A(20) to reference the elements of AA(1) to AA(10) in the
common block:

common /something/ A, AA

where both A and AA are dimensioned 10, then it is *not* correct to
assume that references in your code to A(11) to A(20) should be
replaced with zeros (which is what you were trying to do in your
original post).

Setting A(11) to A(20) to zero would ONLY be correct if AA(1) to AA(10)
were ALWAYS ALL zero, and although this may be true at the start of the
program, it would be unlikely in general to remain true throughout the
programs execution.

So, if this trick is being used (and you will have to read the original
code carefully to check) then you should NOT replace references to
out-of-bounds elements of A with zeros. Instead you should instead
replace them with references to the elements of the array AA to which,
by dint of the trick Richard described, they are referring.

Whether or not A and AA are being initialised to zero by your code
and/or by your compiler would then be a separate, but also important
issue.

Good luck! Updating old code is rarely any fun...

Andy

PS: This whole discussion is assuming that the original authors knew
what they were doing and got it right... let's hope so! You should
perhaps read the code carefully to check their algorithms really do
match with the "out-of-bounds" array accesses they actually use.

andy2O

2005-09-15, 7:57 am

andy2O wrote:

>
> OK... but be very careful, in light of what Richard Maine said!
>
> Perhaps you've caught on to this, but I'll spell it out in great
> detail, because if you missed it, and change your code without
> understanding, you could be in for a lot of pain!
>
> *IF* your code is using the trick Richard noted, of using elements
> A(11) to A(20) to reference the elements of AA(1) to AA(10) in the
> common block:


PS: What I described covers the trick Richard described, for COMMON
blocks. But if the code uses any of the other more obscure tricks that
Richard alluded to, then you have even more headaches to overcome. They
will probably be harder to spot when you read the code than COMMON
blocks and they will be even harder to tell apart from programming
errors by the original author, so you will really have to study the
algorithm and code in order to know what should be done.

Of course you should NOT CONCLUDE that it is safe to replace
out-of-bounds array elements with zeros in these other cases either....
at least not unless you can prove the algorithm needs zeros.

Infact, now I cannot think of ANY case where you can sensibly replace
out-of-bounds array elements with zeros. It's far more likely to be a
programming bug in the original code which needs correcting, or one of
the tricks Richard mentions, which would require a different
replacement...

Andy

robin

2005-09-15, 9:56 pm

kis wrote in message <1126740502.852498.86100@g43g2000cwa.googlegroups.com>...
>I have two pieces of code:
>
>First code:
>
>program firstcode
>real,allocatable :: a(:)
>allocate(a(10))
>a=10.
>do i=1,20
> print*,a(i)
>enddo
>end program firstcode
>
>
>Second code:
>
>program secondcode
>real a(10)
>a=10.
>do i=1,20
> print*,a(i)
>enddo
>end program firstcode
>
>For unknown reason, the first code gives a(i) NOT equals to zero for
>i>10 and the second code gives a(i) equals to zero for i>10. I compile
>the both codes using COMPAQ VISUAL FORTRAN 6.6 with the "Array and
>String Bounds" (in Runtime) option UNCHECKED.
>
>Does anybody know how to initialize the dynamic array to zero for out
>of bound indices such as above?


Both codes are wrong.

>I am aware that it doesn't make sense. And I personally do not like
>that code. But I have a huge hydrodynamic code (13k lines) that was
>written sometime ago. This code, as it is, has a lot of lines with that
>kind of programming style. Rather than spending too much time on
>changing too much on the code, it would be helpful if there is a way to
>initialize all variables (including dynamic array) to zeros as required
>by the original code.
>I believe there is option in Fortran compiler that allows user to
>initialize variables to zeros without explicitly code it in the body of
>the code.


You say that you have a program containing this kind of thing.
You need to correct such instances.

>Thanks
>Irfan





robin

2005-09-15, 9:56 pm

kis wrote in message <1126751739.985145.190060@z14g2000cwz.googlegroups.com>...
>Ok, probably I am wrong and probably you are right. But, what about the
>second code. This is a static array of size 10. When the index of the
>loop go beyond 10 (i.e. 11, 12, ...., etc), what pops up on (print*,
>a(i)) the screen are zeros. How could we explain that.
>
>Probably it is not quite right to use the term "initializing". And
>probably the best way to illustrate this problem is as follows:
>
>program dumb
>real :: a(10), b(20)
>a=10.
>do i=1,20
> b(i)=2.0*a(i)
>enddo
>end
>
>Rather than writing the code like that it is better writing it as
>follows:
>
>program smart
>real :: a(10), b(20)
>a=10.
>do i=1,20
> if(i.le.10)then
> b(i)=2.0*a(i)
> else
> b(i)=0.0
> endif
>enddo
>end
>
>Both code will give: b(1:10)=20. and b(11:20)=0.0.


No, the first code is wrong, and doesn't give anything in particular.
On many systems, the first code will crash.

Incidentally, the second code could be better written as:
b(1:10) = 2*a(i)
b(11:20) = 0

> Of course, again,
>need to uncheck the "Array and String Bounds" option in CVF 6.6 in the
>first code.


Checking should be enabled.

>The author of the hydrodynamic code that I mentioned above used the
>first version (without if), which is bad. The code, originally was
>written using static arrays. I tried to modify it to allow for dynamic
>arrays. Then this problem arose.
>
>Thanks,
>Irfan





Dave Thompson

2005-09-19, 3:56 am

On Wed, 14 Sep 2005 21:26:08 -0700, glen herrmannsfeldt
<gah@ugcs.caltech.edu> wrote:
<snip>
> As a side note, the AWK language specifies that uninitialized
> array elements are zero. Array elements are created when referenced,
> either read or written. There is a fair amount of overhead to do
> that, though. There are no bounds, so you can't ask if an element
> is or is not in bounds.
>

Especially since AWK subscripts are actually strings; a[0] and a[00]
are the same as a["0"] but separate from a["00"]. You can ask whether
an exact subscript/element is in an array, but there is no ordering
where L <= i <= H exist and others don't. Some implementations may
optimize for subscripts that 'happen' to be the string form of
integers -- IIRC tawk did and recent gawk does.

And the initial value of an uninitialized array element or scalar is
an empty string, which when treated/used as a number has value zero.
Array elements/subscripts can be returned to uninitialized status with
'delete'; scalars cannot, but can be set to an empty string.

- David.Thompson1 at worldnet.att.net
Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2009 codecomments.com