- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I am using in my program integer pointers:
real*8 data(10)
pointer (pData,Data)
nteger*4 NewCnt
pData=0
NewCnt=1
pData=LocalAlloc(LPTR,NewCnt*SizeOf(Data(1)))
...
some assignments
NewCnt=100 ! let say
...
pData=LocalRealloc(pData,NewCnt*SizeOf(Data(1)),IOR(LMEM_ZEROINIT,LMEM_MOVEABLE))
...
When I allocate space for more than 10 array elements (as was declared), I obtain error array bounds exceeded. I do not know what will be total number of elements at the compile time.
In DVF this does not happen (bounds of integer pointers were not checked).
Is there possibility to disable checking bounds of integer pointer arrays (other arays I want to check).
Is there some compiler switch? I did not found it.
Thank for advice
Jakub Zlamal
(I am using integer pointers instead of fortran pointers because it is windows application and allocatable arrays cannot be in data types.)
real*8 data(10)
pointer (pData,Data)
nteger*4 NewCnt
pData=0
NewCnt=1
pData=LocalAlloc(LPTR,NewCnt*SizeOf(Data(1)))
...
some assignments
NewCnt=100 ! let say
...
pData=LocalRealloc(pData,NewCnt*SizeOf(Data(1)),IOR(LMEM_ZEROINIT,LMEM_MOVEABLE))
...
When I allocate space for more than 10 array elements (as was declared), I obtain error array bounds exceeded. I do not know what will be total number of elements at the compile time.
In DVF this does not happen (bounds of integer pointers were not checked).
Is there possibility to disable checking bounds of integer pointer arrays (other arays I want to check).
Is there some compiler switch? I did not found it.
Thank for advice
Jakub Zlamal
(I am using integer pointers instead of fortran pointers because it is windows application and allocatable arrays cannot be in data types.)
Link Copied
5 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
real*8 Data(*)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Quoting - Repeat Offender
real*8 Data(*)
I used
real*8 Data(10)
to see first 10 elements.
Now I am using very big array declaration Data(1000) when I know that # of elements does not exceed 1000.
Jakub Zlamal
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Quoting - Quba
I am using integer pointers instead of fortran pointers because it is windows application and allocatable arrays cannot be in data types.
Could you elaborate a bit more on this restriction? At face value I don't think it is right, but maybe I'm missing something.
If you are using recent Intel Fortran releases you could perhaps use the C interoperability features of F2003 to make your life easier(*). As food for thought - in the following example LocalAlloc and friends are used (presumably for some unspecified good reason?) to provide the backing storage for a standard Fortran array pointer. With appropriate compiler flags you get full, working bounds checking too.
[cpp]!*******************************************************************************
!> Example of how to use Local* Win32 functions with "normal" fortran pointers.
!*******************************************************************************
PROGRAM LocalPtrDemo
USE ISO_C_BINDING, ONLY: C_F_POINTER, C_LOC
USE IFWIN
IMPLICIT NONE
REAL(8), POINTER :: my_array(:)
INTEGER, PARAMETER :: real8_size = 8
INTEGER my_size
INTEGER rc
!*****************************************************************************
! Use Win32 to allocate the underlying storage for our array.
my_size = 1
CALL C_F_POINTER( &
IntToCPtr(LocalAlloc(LPTR, my_size * real8_size)), &
my_array, &
[my_size] )
my_array(1) = 10.0
WRITE (*, 200) 'First element:', my_array(1)
! Change our minds about the size of that storage.
my_size = 100
CALL C_F_POINTER( &
IntToCPtr(LocalReAlloc( CPtrToInt(C_LOC(my_array)), &
my_size * real8_size, IOR(LMEM_ZEROINIT, LMEM_MOVEABLE) )), &
my_array, &
[my_size - 1] ) ! Deliberately shortened to demonstrate bounds check
WRITE (*, 200) 'First element (after re-alloc):', my_array(1)
! This would cause bounds check error because we've used my_size -1 above.
!WRITE (*, 200) 'Last element (after re-alloc):', my_array(100)
WRITE (*, 200) 'Last element (after re-alloc):', my_array(99)
! Fortran "knows" how big the array is
WRITE (*, 210) SIZE(my_array)
! Release the underlying storage.
rc = LocalFree(CPtrToInt(C_LOC(my_array)))
IF (rc /= 0) THEN
WRITE (*, 100) 'LocalFree failed'
END IF
100 FORMAT(A)
200 FORMAT(A,F10.1)
210 FORMAT('my_array is ',I0,' elements in size')
CONTAINS
!*****************************************************************************
!> Converts an INTEGER(HANDLE) (that is actually a C-pointer), to a C_PTR
!*****************************************************************************
FUNCTION CPtrToInt(cp)
USE ISO_C_BINDING, ONLY: C_PTR
! Arguments
TYPE(C_PTR), INTENT(IN) :: cp
! Return type
INTEGER(HANDLE) CPtrToInt
!***************************************************************************
CPtrToInt = TRANSFER(cp, CPtrToInt)
END FUNCTION CPtrToInt
!*****************************************************************************
!> Converts a C_PTR to an INTEGER(HANDLE)
!*****************************************************************************
FUNCTION IntToCPtr(int)
USE ISO_C_BINDING, ONLY: C_PTR
! Arguments
INTEGER int(HANDLE)
! Return type
TYPE(C_PTR) IntToCPtr
!***************************************************************************
IntToCPtr = TRANSFER(int, IntToCPtr)
END FUNCTION IntToCPtr
END PROGRAM LocalPtrDemo[/cpp]
(*) Note emphasis on perhaps!
I use the transfer function to convert between the IFWIN style INTEGER(HANDLE) values returned by the Windows API and the F2003 TYPE(C_PTR) values. This might be a bit dodgy, is inherently not portable (but I guess so is use of IFWIN) and there might as a result be some 32/64 issues that I've not thought of. An alternative to transfer would be to write your own "one-liner" C functions that cast a void* pointer to integer or vice versa. I've also hardwired REAL(8)'s storage requirement to be 8 bytes - in a few years time I might be using the C_SIZEOF intrinsic instead.
Another possible simplification, if you are only using a few of the Win API's, would be to examine the INTERFACE for each relevant API function in IFWIN and children, and rewite the interface to take C_PTR's rather than INTEGER(LPVOID) or whatever.
IanH
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank for Your answer, it looks very nice.
My problem is that my code is very old (10 years originally compiled by CVF) and I am using WIN API very much (it is MDI windows application not using QuickWin) so integer pointers are everywhere. But I think it will be usefull to implement Your code.
On line 61 should probably be:
INTEGER(HANDLE) int
Jakub
My problem is that my code is very old (10 years originally compiled by CVF) and I am using WIN API very much (it is MDI windows application not using QuickWin) so integer pointers are everywhere. But I think it will be usefull to implement Your code.
On line 61 should probably be:
INTEGER(HANDLE) int
Jakub
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Quoting - Quba
On line 61 should probably be:
INTEGER(HANDLE) int
INTEGER(HANDLE) int
Oops. Most definitely. An INTENT(IN) attribute wouldn't go astray either.
Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page