- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dear Colleagues! Please help me overcome the problem. As soon as I turn to the GetOpenFileName program, an error "forrtl: severe (41): usufficiant virtual memory" immediately occurs when opening the test file "test.dat". does not work on all versions of compilers (11,18,19). I would be grateful for your help!
program fileopenroot
use nozspe
call initarrs
end
subroutine fileopen(file_spec,ilen)
use comdlg32
use user32
implicit none
character(512) :: file_spec
integer ilen
type(T_OPENFILENAME) ofn
integer*4 NFOBR,status
integer*4 in1
character(*),parameter :: filter_spec = &
"Text Files"C//"*.dat"C// &
"Fortran Files"C//"*.dat;"C
character*512 OIFIL
ofn%lStructSize = SIZEOF(ofn)
ofn%hwndOwner = GetForegroundWindow()
ofn%hInstance = NULL ! For Win32 applications, you
! can set this to the appropriate
! hInstance
!
ofn%lpstrFilter = loc(filter_spec)
ofn%lpstrCustomFilter = NULL
ofn%nMaxCustFilter = 0
ofn%nFilterIndex = 1 ! Specifies initial filter value
ofn%lpstrFile = loc(file_spec)
ofn%nMaxFile = sizeof(file_spec)
ofn%nMaxFileTitle = 0
ofn%lpstrInitialDir = NULL ! Use Windows default directory
ofn%lpstrTitle = loc(""C)
ofn%Flags = OFN_PATHMUSTEXIST
ofn%lpstrDefExt = loc("txt"C)
ofn%lpfnHook = NULL
ofn%lpTemplateName = NULL
status = GetOpenFileName(ofn)
if (status .eq. 0) then
type *,'No file name specified'
else
ilen = INDEX(file_spec,CHAR(0))
type *,'Filespec is ',file_spec(1:ilen-1)
if (IAND(ofn%flags,OFN_READONLY) /= 0) &
type *,'Readonly was requested'
end if
NFOBR=58
OIFIL="d:/test.dat"C
in1=108000000
OPEN(NFOBR,FILE=trim(OIFIL),STATUS='unknown',ACCESS='DIRECT',RECL=in1,FORM='UNFORMATTED',SHARED)
WRITE(NFOBR,REC=1) IN1
CLOSE(NFOBR)
OPEN(NFOBR,FILE=trim(OIFIL),STATUS='unknown',ACCESS='DIRECT',RECL=in1,FORM='UNFORMATTED',SHARED)
READ(NFOBR,REC=1) IN1
CLOSE(NFOBR)
return
end
subroutine InitArrs
use nozspe
character*512 :: file_spec = ""C
integer*4 ilen
allocate (ASHM(Ndim1D),ASHN(Ndim1D),SHM(Ndim1D),SHN(Ndim1D),AASHM(Ndim1D+1),AASHN(Ndim1D+1))
allocate (D(ndimB),P(ndimB),T(ndimB),E(ndimB),WM(ndimB),WN(ndimB),TMPARR((ndimB+Ndim1D)*2),TMPARR2((ndimB+Ndim1D)*2))
allocate (DFUEL(ndimB))
allocate (EP1(ndimB))
allocate (ASHL(Ndim1D),VLine(Ndim1D*20),DENS(ndimB))
allocate (ninfpl(ndimB),ninf(ndimB))
allocate (NWaveV(Ndim1D),ovol(ndimB),OWaveV(Ndim1D))
call fileopen(file_spec,ilen)
return
end
module nozspe
IMPLICIT REAL*8 (A-H,P-Z), LOGICAL*1 (O)
INTEGER,parameter :: ndim=3000,LdimB=3000,ndimB=10000000
INTEGER,parameter :: Ndim1D=10001
real(8), allocatable, dimension(:):: ASHM,ASHN,SHM,SHN,AASHM,AASHN,D
real(8), allocatable, dimension(:):: P,T,E,WM,WN,TMPARR
real(8), allocatable, dimension(:):: DFUEL,TMPARR2,EP1,ASHL
real(8), allocatable, dimension(:):: VLine,DENS
integer, allocatable, dimension(:):: NWaveV,ninfpl,ninf
logical(1), allocatable, dimension(:):: ovol,OWaveV
end module nozspe
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I think that for your particular system, that 400KB allocation is right on the edge of what your system can handle, and calling GetOpenFileName caused Windows to allocate some more, pushing you over the edge. On my PC, it made no difference - it failed either way.
Do you really need a RECL that long? What exactly are you trying to do here? I agree that Xeffort is not yet 64-bit ready (and may never be.)
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
If you comment out the GetOpenFileName statement, the program works without errors.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Well I glanced down your code and the first thing that jumped out at me was I have had issues with making null terminated C strings with the non-standard "text"C syntax. I always use "text"//achar(0). But the second thing that I note is that filter_spec needs double null termination at the end //achar(0)//achar(0) the first null ending the last string and the second ending the string list.
It may be that without that the SDK routine goes looking further along in memory for that non-existent termination and then bad things happen.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dear andrew_4619!
This is a standard example that comes with the compiler. Unfortunately, replacing with // achar (0) did not fix the problem. Thank you!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
GetOpenFileName is a dummy call, you can select any file on the disk.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
If you insist on using the C notation you will still need:
character(*),parameter :: filter_spec = & "Text Files"C//"*.dat"C// & "Fortran Files"C//"*.dat;"C//""C
note I changed the end of the string.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dear andrew_4619!
I do not insist in any way, I just state the fact that neither one nor the other method proposed by you solved the problem. Thank you!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
program fileopenroot
use nozspe
call initarrs
end
subroutine fileopen(file_spec,ilen)
use comdlg32
use user32
implicit none
character(512) :: file_spec
integer ilen
type(T_OPENFILENAME) ofn
integer*4 NFOBR,status
integer*4 in1
character(*),parameter :: filter_spec = &
"Text Files"//char(0)//"*.dat"//char(0)// &
"Fortran Files"//char(0)//"*.dat;"//char(0)//char(0)
character*512 OIFIL
ofn%lStructSize = SIZEOF(ofn)
ofn%hwndOwner = GetForegroundWindow()
ofn%hInstance = NULL ! For Win32 applications, you
! can set this to the appropriate
! hInstance
!
ofn%lpstrFilter = loc(filter_spec)
ofn%lpstrCustomFilter = NULL
ofn%nMaxCustFilter = 0
ofn%nFilterIndex = 1 ! Specifies initial filter value
ofn%lpstrFile = loc(file_spec)
ofn%nMaxFile = sizeof(file_spec)
ofn%nMaxFileTitle = 0
ofn%lpstrInitialDir = NULL ! Use Windows default directory
ofn%lpstrTitle = loc(""//char(0))
ofn%Flags = OFN_PATHMUSTEXIST
ofn%lpstrDefExt = loc("txt"//char(0))
ofn%lpfnHook = NULL
ofn%lpTemplateName = NULL
status = GetOpenFileName(ofn)
if (status .eq. 0) then
type *,'No file name specified'
else
ilen = INDEX(file_spec,CHAR(0))
type *,'Filespec is ',file_spec(1:ilen-1)
if (IAND(ofn%flags,OFN_READONLY) /= 0) &
type *,'Readonly was requested'
end if
NFOBR=58
OIFIL="d:/test.dat"//char(0)
in1=108000000
OPEN(NFOBR,FILE=trim(OIFIL),STATUS='unknown',ACCESS='DIRECT',RECL=in1,FORM='UNFORMATTED',SHARED)
WRITE(NFOBR,REC=1) IN1
CLOSE(NFOBR)
OPEN(NFOBR,FILE=trim(OIFIL),STATUS='unknown',ACCESS='DIRECT',RECL=in1,FORM='UNFORMATTED',SHARED)
READ(NFOBR,REC=1) IN1
CLOSE(NFOBR)
return
end
subroutine InitArrs
use nozspe
character*512 :: file_spec = ""//char(0)
integer*4 ilen
allocate (ASHM(Ndim1D),ASHN(Ndim1D),SHM(Ndim1D),SHN(Ndim1D),AASHM(Ndim1D+1),AASHN(Ndim1D+1))
allocate (D(ndimB),P(ndimB),T(ndimB),E(ndimB),WM(ndimB),WN(ndimB),TMPARR((ndimB+Ndim1D)*2),TMPARR2((ndimB+Ndim1D)*2))
allocate (DFUEL(ndimB))
allocate (EP1(ndimB))
allocate (ASHL(Ndim1D),VLine(Ndim1D*20),DENS(ndimB))
allocate (ninfpl(ndimB),ninf(ndimB))
allocate (NWaveV(Ndim1D),ovol(ndimB),OWaveV(Ndim1D))
call fileopen(file_spec,ilen)
return
end
- 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
I am guessing that perhaps if you had done the file dialog before the allocated it would have worked but maybe the last allocate might have failed ? I usually have STAT= on all allocates to check they worked and stop a potential crash.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Without operator GetOpenFileName there were no problem with allocate of memory (16 Gb). Yes, now I also will use "Stat" )).
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
No, the code you are using is NOT the example that comes with the compiler. I should know, as I wrote the example (or at least revised it at one time.)
This is the example and it works:
program fileopen
use comdlg32
implicit none
! Declare structure used to pass and receive attributes
!
type(T_OPENFILENAME) ofn
! Declare filter specification. This is a concatenation of
! pairs of null-terminated strings. The first string in each pair
! is the file type name, the second is a semicolon-separated list
! of file types for the given name. The list ends with a trailing
! null-terminated empty string.
!
character(*),parameter :: filter_spec = &
"Text Files"C//"*.txt"C// &
"Fortran Files"C//"*.f90;*.f"C//""C
! Declare string variable to return the file specification.
! Initialize with an initial filespec, if any - null string
! otherwise
!
character(512) :: file_spec = ""C
integer status,ilen
ofn%lStructSize = SIZEOF(ofn)
ofn%hwndOwner = NULL
ofn%hInstance = NULL ! For Win32 applications, you
! can set this to the appropriate
! hInstance
!
ofn%lpstrFilter = loc(filter_spec)
ofn%lpstrCustomFilter = NULL
ofn%nMaxCustFilter = 0
ofn%nFilterIndex = 1 ! Specifies initial filter value
ofn%lpstrFile = loc(file_spec)
ofn%nMaxFile = sizeof(file_spec)
ofn%nMaxFileTitle = 0
ofn%lpstrInitialDir = NULL ! Use Windows default directory
ofn%lpstrTitle = loc(""C)
ofn%Flags = OFN_PATHMUSTEXIST
ofn%lpstrDefExt = loc("txt"C)
ofn%lpfnHook = NULL
ofn%lpTemplateName = NULL
! Call GetOpenFileName and check status
!
status = GetOpenFileName(ofn)
if (status .eq. 0) then
type *,'No file name specified'
else
! Get length of file_spec by looking for trailing NUL
ilen = INDEX(file_spec,CHAR(0))
type *,'Filespec is ',file_spec(1:ilen-1)
! Example of how to see if user said "Read Only"
!
if (IAND(ofn%flags,OFN_READONLY) /= 0) &
type *,'Readonly was requested'
end if
end program fileopen
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dear Steve! Of course the original code has been changed. The reference concern using // char (0) instead of "" C . For me, the question remained unclear, how such an insignificant programm GetOpenFileName could cause problems with long memory addressing. Does this mean there is a problem with the GetOpenFileName program? Can you answer as a Fortran Guru?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
GetOpenFileName is a standard part of the windows system used in many thousands of applications, it is not Fortran specific. It is unlikely there is a problem with it as lots of people would have a problem. You have experience a memory addressing problem that can have many potential causes. The missing double null termination in your code was a bug, it may not be related to the problem you experienced but is still a bug as the routine would search beyond your string until it found a null address or hit a predefined buffer limit value. The results of that would be hard to predict.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
"Insignificant" nothing is insignificant with memory.
The insignificant statement :
strcpy(from,to);
will certainly cause an access violation in memory if there is no char(0) at the end of string from.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
There is no difference between ""C and CHAR(0), other than that ""C is non-standard.
The program you posted above is incomplete, as it uses a module you did not supply.
- 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
Ok. The immediate cause of the Insufficient virtual memory error is:
in1=108000000
OPEN(NFOBR,FILE=trim(OIFIL),STATUS='unknown',ACCESS='DIRECT',RECL=in1,FORM='UNFORMATTED',SHARED)
You are opening the file with a RECL of 108000000*4 bytes, or 432,000,000 bytes. As part of the OPEN, the run-time library allocates a buffer large enough to hold a whole record. At least in a 32-bit configuration, that large a single allocation fails. If I build the program as x64, the OPEN succeeds.
The use of GetOpenFileName is a "red herring" - it has no effect on the OPEN problem. I removed the call and still saw the error.
One other error I spotted is this:
OIFIL="d:/test.dat"//char(0)
Do not append a NUL to file specifications you'll use in OPEN. This is probably harmless, but is still an error.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks a lot, Steve! Unfortunately, I have to write an application under win32 because of I use the Xeffort library. I am not such an experienced user of visual fortran. I tried unsuccessfully to convert this library to win64 (((. This library helped me to draw directly inside of the QWin dialogue, for example.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
But nevertheless compare 2 results
Maybe I am stupid, but I can't finally understand this result. (I understand your explanation concern Open, etc).
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page