Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

a kind of an assumed-shape array leads to a sig11

2 views
Skip to first unread message

Thomas Lang

unread,
Nov 13, 2011, 4:29:26 PM11/13/11
to
Dear all,

the program below is a boiled down version of a significant larger
program which runs smoothly, until n becomes larger than, e.g., n =
30000. The latter is still not excessively large but leads to a
segmentation fault 11. Changing the 'assumed-shape' array to an
allocatable and explicitly allocating it within the subroutine like
that

subroutine baz()
use bar
integer, dimension(:), allocatable :: a
allocate(a(n))
deallocate(a)
end subroutine baz

circumvents the problem. Why? Is using a module-variable to define the
extent of an array in a subroutine bad practice?

Thanks for your help!

Thomas

!--------------------------------------------------------
module bar
integer :: n
end module bar

subroutine baz()
use bar
integer, dimension(n) :: a
end subroutine baz

program foo
use bar
n = 4
call baz()
end program foo
!--------------------------------------------------------

dpb

unread,
Nov 13, 2011, 5:01:04 PM11/13/11
to
On 11/13/2011 3:29 PM, Thomas Lang wrote:
> Dear all,
>
> the program below is a boiled down version of a significant larger
> program which runs smoothly, until n becomes larger than, e.g., n =
> 30000. The latter is still not excessively large but leads to a
> segmentation fault 11. Changing the 'assumed-shape' array to an
> allocatable and explicitly allocating it within the subroutine like
> that
>
> subroutine baz()
> use bar
> integer, dimension(:), allocatable :: a
> allocate(a(n))
> deallocate(a)
> end subroutine baz
>
> circumvents the problem. Why? Is using a module-variable to define the
> extent of an array in a subroutine bad practice?
...
> !--------------------------------------------------------
> module bar
> integer :: n
> end module bar
>
> subroutine baz()
> use bar
> integer, dimension(n) :: a
> end subroutine baz
>
> program foo
> use bar
> n = 4
> call baz()
> end program foo
> !--------------------------------------------------------

Looks fine to me.

No chance you somehow compiled w/ a flag that has the effect of making
default INTEGER 16-bits, I don't suppose? The 30K+/- makes me suspicious.

--

Aris

unread,
Nov 13, 2011, 5:21:37 PM11/13/11
to
I cannot say what goes wrong, but I want to say that I always try to
avoid this construction and prefer one of the following:
make n parameter
give n as input to baz
make a allocatable

FX

unread,
Nov 13, 2011, 5:50:17 PM11/13/11
to
> subroutine baz()
> use bar
> integer, dimension(n) :: a
> end subroutine baz
>
> program foo
> use bar
> n = 4
> call baz()
> end program foo

Looks like a stack size issue (particularly if you're on Windows, which
IIRC has a rather small default stack size). But 3000 is quite low to
trigger it, though.

--
FX

Richard Maine

unread,
Nov 13, 2011, 5:53:00 PM11/13/11
to
Thomas Lang <archduk...@googlemail.com> wrote:

> the program below is a boiled down version of a significant larger
> program which runs smoothly, until n becomes larger than, e.g., n =
> 30000. The latter is still not excessively large but leads to a
> segmentation fault 11. Changing the 'assumed-shape' array to an
> allocatable and explicitly allocating it within the subroutine...
> circumvents the problem. Why? Is using a module-variable to define the
> extent of an array in a subroutine bad practice?
>
> !--------------------------------------------------------
> module bar
> integer :: n
> end module bar
>
> subroutine baz()
> use bar
> integer, dimension(n) :: a
> end subroutine baz
>
> program foo
> use bar
> n = 4
> call baz()
> end program foo
> !--------------------------------------------------------

Nothing really wrong with this, though note that it is *NOT* an
assumed-shape array. Glad you posted the actual code instead of just
using that description alone. An assumed-shape array is a dummy argument
that gets its shape from the actual argument. You don't have a dumy
argument at all.

What you do have is an automatic array. It is a local (non-dummy) array
that is automatically allocated on entry to the subroutine and
deallocated on exit, without needing explicit allocate or deallocate
statements.

This is perfectly fine standard Fortran. No, it isn't considered bad
practice. One problem with automatic arrays is that there is no way for
you to do error handling if the allocation fails, but that's not much f
an issue if you weren't planning to do such error handling anyway.

What you are almost certainly running into is the unreasonably small
default stack size limits on many current systems. Those small stack
size limits, combined with the tendency of compilers to put automatic
arrays on the stack, causes the error you are seeing.

There are 3 solutions.

1. Some compilers have options to avoid putting large automatic arrays
on the stack. Details depend on the particular compiler. Some might even
handle it well by default.

2. Most systems have a way to increase the stack size limit. That's my
preferred approach. There's really no god reason for the limit to be so
small. Yes, I've heard explanations of why it is that small; I don't
consider them very good ones, though. They address arcane cases you will
probably never see and performance differences so small you probably
can't measure them, but the problems caused by the small stack limit pop
up all the time.... including in regular questions here.

3. Well, you could code around it by avoiding the use of automatic
arrays, as you suggested. But in my opinion that's the wrong approach.
It is perfectly fine code. If you do choose that, it isn't because there
is anything wrong with your original code. Instead, you are working
around things that are poor about the implementation. One can debate how
much of the flaw lies in the compilers versus the operating systems, but
it isn't in your code.

--
Richard Maine | Good judgment comes from experience;
email: last name at domain . net | experience comes from bad judgment.
domain: summertriangle | -- Mark Twain

Richard Maine

unread,
Nov 13, 2011, 5:56:24 PM11/13/11
to
Aris <us...@7qb4q8.invalid> wrote:

> Thomas Lang <archduk...@googlemail.com> wrote:

> > !--------------------------------------------------------
> > module bar
> > integer :: n
> > end module bar
> >
> > subroutine baz()
> > use bar
> > integer, dimension(n) :: a
> > end subroutine baz
> >
> > program foo
> > use bar
> > n = 4
> > call baz()
> > end program foo
> > !--------------------------------------------------------
>
> I cannot say what goes wrong, but I want to say that I always try to
> avoid this construction and prefer one of the following:
> make n parameter
> give n as input to baz
> make a allocatable

If by "give n as input to baz", you mean to make n a subroutine
argument, then that will presumably have the same result because the
array would still be an automatic one.

baf

unread,
Nov 13, 2011, 8:00:23 PM11/13/11
to
On 11/13/2011 1:29 PM, Thomas Lang wrote:
> subroutine baz()
> use bar
> integer, dimension(:), allocatable :: a
> allocate(a(n))
> deallocate(a)
> end subroutine baz
>
> circumvents the problem. Why? Is using a module-variable to define the
> extent of an array in a subroutine bad practice?
>
> Thanks for your help!
>
> Thomas
>
> !--------------------------------------------------------
> module bar
> integer :: n
> end module bar
>
> subroutine baz()
> use bar
> integer, dimension(n) :: a
> end subroutine baz
>
> program foo
> use bar
> n = 4
> call baz()
> end program foo

Not sure which compiler or operating system you are using, but I tried
your program with n=340000 and it works fine with the 32-bit version of
gfortran running on a windows machine.

Thomas Lang

unread,
Nov 14, 2011, 4:48:03 AM11/14/11
to
On 13 Nov., 23:53, nos...@see.signature (Richard Maine) wrote:
Dear Richard and FX,

a stack problem it was! Telling the compiler to put arrays into heap
instead of stack solved the problem. Testing my code on a Mac (where
stack is limited and cannot be set to unlimited) was the problem, but
I guess I'll have to do the same, or increase the stack limit, on the
clusters I run the code on, as well.

Thanks for your prompt help! It's nice to see the Fortran community
alive and well!

Cheer,

Thomas

0 new messages