Re: Question about arrays of derived types and POINTERs
- From: Mark Stucky <mstucky5@xxxxxxx>
- Date: Sun, 03 Aug 2008 19:47:41 -0400
Rich Townsend wrote:
Richard Maine wrote:Mark Stucky <mstucky5@xxxxxxx> wrote:
I'm fairly certain that I'm still
missing something with regard to understanding POINTERs,...
Likely. See below.
call alloc_surf(surfptr,ni,nj,status)
surf(n) = surfptr
It isn't directly related tp your question, but the above strikes me as
oddly indirect and complicated. I'm not sure why you don't just directly
initialize surf(n) instead of allocating a temporary surfptr and then
copying its target to surf(n). That is just do
call alloc_surf(surf(n),ni,nj,status)
and, of course, get rid of the pointer attribute and the corresponding
allocation/deallocation in alloc_surf. Perhaps there is some reason that
didn't show through in my quick glance, or even was elided from the
posted code.
I agree that the above is "oddly indriect and complicated". Originally
I tried to allocate "surf(n)" directly via
call alloc_surf(surf(n),ni,nj,status)
but I was getting either a compile time or run time error, I don't
remember at the moment.
I had meant to mention this in the original post but simply forgot.
Anyway, on to the more central part.
if (associated(a)) then...
deallocate(a)
endif
if (associated(surf)) then
deallocate(surf)
endif
The above are both problems. Looks to me like you are making one of the
many common mistakes with pointers. Unless you do something specific to
make it otherwise, a pointer starts "life" with an undefined association
status.
As glen herrmannsfeldt wrote in another post, this was part of the
problem.
glen herrmannsfeldt wrote:
> Mark Stucky wrote:
> (snip)
>
>> if (associated(a)) then
>> deallocate(a)
>> endif
>
> I am suspicious of the above statements (in two places).
>
> Running with g95, it fails in the deallocate statement above.
>
> Commenting out both of those, it runs and gives the desired
> result. That is, both "correct" and "incorrect" output
> are the same.
>
> Deallocating memory that hasn't been allocated does very
> strange things to the memory that is allocated.
>
> -- glen
After trying glen's "fix", I am also getting the correct output.
Undefined association status is *NOT* the same thing as disassociated.
Instead, it means that you are not allowed to do much of anything with
the pointer. Very specifically, that means you are not allowed to use
the associated intrinsic to inquire whether it is associated or not. The
associated intrinsic is only for distinguishing between associated vs
disassociated when you have separately ruled out the possibility of
undefined association status.
In your case, you inquire about the association status before you have
done anything at all to the pointer, which means its status will indeed
be undefined. That makes the program illegal, though not in a way that
compilers are required to detect. This error can cause all kinds of
confusing symptoms. The associated() intrinsic can return misleading and
inconsistent values, resulting in apparently contradictory behavior.
Undefined association status is one of the things you have to be very
careful about with pointers. (And it isn't particularly unique to
Fortran.)
If it helps, think of the fact that the system has to store the
association information about the pointer somewhere. If the location
where that information is stored isn't initialized, it can have random
garbage in it.
You could probably fix this by nullifying surfptr initially and
nulifying the x, y, and z pointers in each element when you initialize
that element. Or you can achieve simillar effects by declaring the
derived type to have default initialization for those elements.
Yes, I know, pointers can be tricky!
I've used them many times in several different languages over the past
25 years. This was the first "non-trivial" thing I had attempted with
f90 code.
In the "real" application, I think that I am a little more careful with
regard to checking/handling the status of pointers, although after a
quick check, I can see that I've missed a few.
To expand to what Richard said, you can initialize pointer components like this:
type(typ_2D_array),pointer :: x => null()
(Note: this is a Fortran 95 feature, so you're compiler will have to be F95 or more recent).
Turns out that this is supported in my compiler...
I won't swear this is your (only) problem; I didn't study carefully
enough to see if it would likely give the symptoms you saw. But it is
definitely *A* problem and has at least decent odds of being "the"
problem.
Thanks for your help. Between your's, glen's and Richard's suggestions,
I think that I can get a little further now.
Thanks again,
--Mark
.
- References:
- Re: Question about arrays of derived types and POINTERs
- From: Richard Maine
- Re: Question about arrays of derived types and POINTERs
- From: Rich Townsend
- Re: Question about arrays of derived types and POINTERs
- Prev by Date: Re: forrtl: severe (174): SIGSEGV due to output file.
- Next by Date: Re: Question about arrays of derived types and POINTERs
- Previous by thread: Re: Question about arrays of derived types and POINTERs
- Next by thread: Re: Question about arrays of derived types and POINTERs
- Index(es):