- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
I wrote this simple code (see below) that converts an array of real into a very long string of characters.
I have been running this little code on 2 different machines and I compiled it with the same compler on both machines :
Intel(R) Fortran Intel(R) 64 Compiler XE for applications running on Intel(R) 64, Version 14.0.1.106 Build 20131008
Copyright (C) 1985-2013 Intel Corporation. All rights reserved.
Both machines are equipped with Intel processors,
- one with processors like : Intel(R) Xeon(R) CPU E5472 @ 3.00GHz
- and the other one with processor like : Intel(R) Xeon(R) CPU E5506 @ 2.13GHz
While on machine 1, the code works fine, on machine 2, I get a "Segmentation fault (core dumped)" message most of the time with n = 2093504.
So, is there a maximum character length allowed that is machine-dependant? How can I know this maximum?
Regards,
F.
program test implicit none integer :: i real, allocatable :: cube(:) integer :: n, length n = 2093503 ! OK n = 2093504 ! Segmentation fault length = 4*n write(*,*) n, length if (.not. allocated(cube)) allocate(cube(n)) do i = 1, n call random(cube(i)) end do call sub(cube, n, length) end program subroutine sub(array, n, length) implicit none integer :: n, len real :: array(n), f character(length) :: buf character(4) :: c integer :: i equivalence(f, c) write(*,*) n, length do i = 1, n f = array(i) buf(4*(i-1)+1:4*(i-1)+4) = c(1:4) end do end subroutine sub
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The issue on the system that fails relates to exhausting the available shell stack space related to the creation of stack-based arrays.
You can check the shell stack space with either ulimit -s (bash) or limit stacksize (csh).
To change either, use: ulimit -s <value> or limit stacksize <value>, where <value> is specified in kbytes. <value> can also be specified as: unlimited
For additional information about this type of failure refer to Determining Root Cause of Segmentation Faults SIGSEGV or SIGBUS errors
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks Kevin,
That was it.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The correct way to have fixed this is with the foreknowledge that "length" is very large in
character(length) :: buf
would be to use:
character(:), allocatable :: buf
...
allocate (character(length)::
buf)
The "ulimit" is fine if, and only if, the program is, and will always remain, single threaded.
BTW insert a test for allocation failure such that you can take appropriate action.
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You can search the documentation index for "compiler limits". Online, the page for that is here.
I note that we don't document a limit for character lengths - the theoretical limit is 2**31-1 for IA-32 and 2**63-1 for Intel 64. I will suggest that we add this to the documentation.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@Jim, I learned something. I didn't know one could do this : allocate (character(length)::buf)
I'll try that.
@Steve, good idea.
Thank you.
F.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
fuji s. wrote:
@Jim, I learned something. I didn't know one could do this : allocate (character(length)::buf)
...
Do not forget to add the allocation status test as suggested by Jim:
ALLOCATE( CHARACTER(LEN=DesiredLength) :: buf, STAT=IntErrorCodeVar) IF (IntErrorCodeVar /= 0) THEN !.. Handle the error
It's good to do so as a general practice, but especially important in your case as your string length will be stretching your system resources.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
I tried to allocate a character string works and it works well too even when the stacksize is low.
Thank you all for your help.
F.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You rarely have to explicitly allocate an allocatable, deferred-length character value. Just assign to it and the allocation is handled automatically. However, if you are passing such a variable to a procedure which writes to it, you may need to allocate it first.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You also may want to explicitly allocate the deferred-length character value when you know the length is very large and may experience an allocation failure. (Such as in the original poster's example.)
Jim Dempsey
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page