- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
ALLOCATE (STRING(LRECL))
I then pass it to a subroutine where is is defined as CHARACTER RECORD*(*). Before V12, L=LEN(RECORD) gave me the length of STRING, and I then knew how big a record I could put in STRING. In V12, L is now one, the length of one element of STRING.
My question is this: Is there anyway with Fortran 2003 to allocate such a character string of a programatically deetermined length, pass it to a subroutine which determines it's length, and fills it without reallocating it with each read? Is there any way to allocate a character variable that doesn't get reallocated all the time?
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Do you mean like...
[fortran] CHARACTER(:), ALLOCATABLE :: string
INTEGER :: LRECL
LRECL = programmatically_determined_length()
ALLOCATE(CHARACTER(LRECL):: string)
CALL a_subroutine(string)
!...
SUBROUTINE a_subroutine(record)
CHARACTER(*), INTENT(OUT) :: record
INTEGER :: i
!****
DO i = 1, LEN(record)
record(i:i) = ACHAR(MOD(i-1,26)+IACHAR('A'))
END DO
END SUBROUTINE a_subroutine
[/fortran]
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
READ(DCB%HANDLE,'(A)',SIZE=VLEN,IOSTAT=IO_STATUS,ADVANCE='NO') BUFFER
IF (IS_IOSTAT_END (IO_STATUS)) THEN
EOF=.TRUE.
VLEN=0
ELSEIF (VLEN .GT. 0) THEN
RECORD(1:MIN(L,VLEN))=BUFFER(1:VLEN)
ENDIF
So it reads into a static buffer, then fills record, up to the length of the allocated record; L is as mentioned previously, from L=LEN_TRIM(RECORD). My concernis that RECORD remain at a fixed allocation as passed down to the routine and not thrash around with reallocation when reading, e.g., 100,000 records. I think I can allocate a character array and pass the length separately, but was hoping to still take advantage of the length passed by convention.
Ihave several other places where this is a problem, and calls to this routine where it is not a problem, and I'll haveto do a lot of weedingthem all out to fix this if there is no good answer.
I was thinking allocated character variables would be a boon for me, but in fact they are turning out to be trouble. Before, I could set a pointer to an allocated character 1xn array and get it treated as a character string, but that no longer works either.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Just replace the DO loop in the a_subroutine procedure in my snippet with your read-into-buffer-and-copy-to-record-code. There will only be one allocation - at the allocate statement. All subsequent calls to a_subroutine will use the same storage. No thrashing. The length of the scalar that was allocate gets passed along automatically too if the corresponding dummy argument is assumed length.
Or are you seeing somethng different?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Try using SIZEOF(RECORD)
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
CHARACTER(:), ALLOCATABLE :: STR
ALLOCATE (STR(100))
STR = ' '
then STR will, after the assignment, be length 1 not 100.
I would be interested in seeing code that changed behavior in V12. We have fixed some bugs in this area and it could be you were depending on buggy behavior. Or we may have introduced a bug.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
When the allocated string is in a module, I assume it changes whenever used, so one can't centrally allocate strings for which you don't want the length to change aftger allocation.
I was using V10 before. The main change seems to be the length passed to a subroutine is the element length, not the total length. I can't verify this anymore, not having V10 available, but that's where I ran into problems.
Another difference is that you can't allocate a 1 x n string array, and define a pointer to it as a character variable, which worked in F95:
CHARACTER,ALLOCATABLE,TARGET:: S1(:),S2(:),S3(:)
CHARACTER(5000),POINTER:: BOUNDS,RESTRICT,ESTIMATES
ALLOCATE (S1(5000),S2(5000),S3(5000))
BOUNDS=>S1(1);RESTRICT=>S2(1);ESTIMATES=>S3(1)
The rest of the trouble involves my trying to figure out how string allocation works in F2003, which you've cleared up for me; thanks!. Things now seem to make sense wrt the F2003 standard; I just have to check everything carefully and test exhaustively sofware that was stable and ran correctly under V10.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I'm a bit puzzled at the compiler's response to the code you posted in your last reply - I'll look into that.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
[fortran]character(10) str str = 'abcdefghij' call sub (str) ... subroutine sub (arg) character(100) arg ...[/fortran]This is not legal.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Interestingly enough, it seems if you pass a character array down and dimension it as it's exact lenght, e.g., string*length, it gets by the check of the hidden lenght of 1.
I don't think anything needs to be legal that isn't. Just a learning experience for me about character variables, especially dynamic ones, as things that worked (e.g., as character arrays) before or got passed checking didn't with the new compiler. I think I've got all my code compliant now.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
How do you delete a reply? I can only manage to edit one edit one....
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
What version began to support'CHARACTER(:), ALLOCATABLE :: string'. F 10.0.25 complains about a syntax error, or is the error something else?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page