Path: utzoo!attcan!utgpu!jarvis.csri.toronto.edu!rutgers!ukma!psuvm.bitnet!cunyvm!byuvax!hallidayd From: hallidayd@yvax.byu.edu Newsgroups: comp.lang.fortran Subject: Re: Pointer examples and 8x Message-ID: <638hallidayd@yvax.byu.edu> Date: 20 Jun 89 01:38:44 GMT Lines: 92 By the way Walt, even your Fortran 8x example needs only one pointer (for the walk) since (according to your own code, message <158@unmvax.unm.edu>) Fortran 8x allows references of the form TRAIL_PTR % NEXT % NEXT => TMP_PTR thus your code for "walking" through the list may be implemented as SUBROUTINE INSERT (PTR, NUMBER) ! Single pointer version TYPE (NODE), POINTER, INTENT (IN) :: PTR TYPE (NODE), POINTER :: TRAIL_PTR, TMP_PTR INTEGER, INTENT (IN) :: NUMBER ! "Walk" through the list to ! determine where NUMBER goes TRAIL_PTR => PTR DO IF (.NOT. ASSOCIATED (TRAIL_PTR % NEXT)) EXIT IF (NUMBER <= TRAIL_PTR % NEXT % VALUE) EXIT TRAIL_PTR => TRAIL_PTR % NEXT ! Please excuse me if this should ! actually use the = assignment ! operator. (I have not read the ! latest proposed standard yet.) END DO ! Insert into sublist ALLOCATE (TMP_PTR) TMP_PTR % VALUE = NUMBER TMP_PTR % NEXT => TRAIL_PTR % NEXT TRAIL_PTR % NEXT => TMP_PTR END SUBROUTINE INSERT Actually, if I understand the ``Aliasing'' mode for Fortran 8x pointers, Fortran 8x pointers are a lot closer to the concept of true recursive data structures than they are to C style ``addresses''. Thus the construct TRAIL_PTR = TMP_PTR used in Walt's code will accomplish the wrong thing, it will reassign the value of the list node ``pointed to''(aliased) by TRAIL_PTR the value of the next node (the node aliased by TMP_PTR). This will, in effect, delete the original node aliased by TRAIL_PTR and leave a duplicate node, aliased by TMP_PTR, ``dangling'' after the execution of the next statement ( TMP_PTR => TRAIL_PTR % NEXT ). This is an example of how most any form of pointer implementation can allow the programmer to produce erroneous code. (Unless the standard declares that there is NO garbage collection, that code which leaves allocated memory unreferenced is in error, and, further, that constructs which cause such unreferenced allocated memory will be flagged as erroneous by the compiler. However, as has been pointed out by people in the comp.lang.ada news group, there are cases where data structures may be referenced though several different paths and where the program (and thus, all the more so, the compiler) may have no idea whether a given abject has become unreferenced, therefore some form of garbage collection becomes needed---perhaps being turned on or off by compiler directives.) Furthermore, Walt, were you not trying to insert _before_ the node that had a VALUE greater than or equal to the given NUMBER? This is not what your recursive routine _appears_ to do. Instead, it creates a ``dangling'' node, containing the inserted number, pointing to the node _after_ the one with the VALUE greater than or less than the NUMBER. What I expect you wanted was: RECURSIVE SUBROUTINE INSERT (L, NUMBER) TYPE (NODE), POINTER, INTENT(IN OUT) :: L TYPE (NODE), POINTER :: TMP_L INTEGER, INTENT (IN) :: NUMBER ! If NUMBER goes here, insert it in new node IF (NUMBER <= L % VALUE) THEN ALLOCATE (TMP_L) TMP_L % VALUE = NUMBER TMP_L % NEXT => L ! Modified L => TMP_L ! lines ! Otherwise, insert into sublist ELSE CALL INSERT (L % NEXT, NUMBER) END IF END SUBROUTINE INSERT (Just in the interest of accuracy---I hope! ;-) _____________________________________ / David Halliday \ | | | Internet: hallidayd@yvax.byu.edu | | BITNET: hallidayd@byuvax | | Us Mail: BYU Physics Department | | 296 ESC | | Provo, UT 84602 | \_____________________________________/