Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

Possible problem with QSORT ?

lesneilson
Beginner
1,048 Views
Has anyone experienced a problem using QSORT sorting an array which is in COMMON ? (integer*2 array iFitStkPtr(1000) see code below)
I am getting the following (example code also shown below) :

Program halts with dialog box and message :

Unhandled exception at 0x0051a1e0 in clash.exe: 0xC0000005: Access violation reading location 0xffffffff.

In the Output window :

First-chance exception at 0x0051a1e0 in clash.exe: 0xC0000005: Access violation reading location 0xffffffff.

First-chance exception at 0x0050e653 in clash.exe: 0xC0000091: Floating-point overflow.

Setting a breakpoint in the function "fnCompareFitStk" shows it is entered and the exception occurs on exit from "fnCompareFitStk" back to qsort.

The actual number ofitems in iFitStkPtr(nfitstk) is 111 so is not large.

I have managed a workaround so the need is not urgent and the post is for interest.

Thanks

Les

Code:

      subroutine delfit(stkkk,idel)
      use Strucad_Binary_Model 
      use IFPORT 
      implicit none

! COMMON variables

      integer*2, parameter :: iMAXNOCHKFIT=1000
      character(20), dimension(iMAXNOCHKFIT) :: FITSTK
      integer*2, dimension(iMAXNOCHKFIT) :: iFitStkPtr
      integer*2 :: NFITSTK
      common /NOCHKFIT/ FITSTK, iFitStkPtr, NFITSTK

! Arguments

      integer*2, intent (out) :: IDEL
      character(*), intent (in) :: STKKK

! Local variables

      integer*2 :: i, iun, nlen
      character(80) :: cfile
      character(100) :: line
      integer*2 :: iStart
      integer*2 :: iMin, iMax, iMiddle, iStkIndx
      integer (SIZEOF_SIZE_T) iArrayLen,iElementSize

      integer*2, external :: fnCompareFitStk

!--- Read fit stock for the first time

      if (iNoFitLoaded==0) then
        iNoFitLoaded=1
        nfitstk = 0

!--- Open member list file

        call findunit(iun)
        call getdir(modname,'catalog/nochk.fit',cfile)
        open (iun,file=cfile,status='old',err=150)

!--- read a line from file

 50     read (iun,'(a)',err=150,end=150) line
        call txtleng(line,nlen)
        if (nlen<1) goto 50
        if (line(1:1)=='*') goto 50

        do iStart = 1, nlen
          if (line(iStart:iStart)/=' ') goto 100
        end do
        !check if duplicate exists
 100    do i=1,nfitstk
          if (fitstk(i)==line(iStart:nlen)) then
            !have a duplicate
            !WARNING - Duplicate entry in catalog
ochk.fit ()
            call charmsg(1772,line(iStart:nlen))
            goto 50
          end if
        end do
        !check if reached limit
        if (nfitstk==iMAXNOCHKFIT) then
          !Warning - Too many catalog
ochk.fit entries. Maximum 
          call intmsg(1771,iMAXNOCHKFIT)
          goto 150
        end if
        !save stock name 
        nfitstk = nfitstk + 1
        fitstk(nfitstk) = line(iStart:nlen)
        !store pointer
        iFitStkPtr(nfitstk)=nfitstk
        goto 50
 150    close (iun)
        if (n
fitstk>1) then
          !sort list of stock names
          iArrayLen=nfitstk
          iElementSize=2
          call qsort(iFitStkPtr,iArrayLen,iElementSize,
fnCompareFitStk)
        end if
      end if

!--- search for matching stock name using binary search

      idel=1
      iMin=1
      iMax=nfitstk
      do while (iMin<=iMax)
        iMiddle=(iMax+iMin)/2
        iStkIndx=iFitStkPtr(iMiddle)
        if (stkkk==fitstk(iStkIndx)) then
          idel=0
          exit
        else if (stkkk


0 Kudos
4 Replies
jim_dempsey
Beginner
1,048 Views

The error message

Unhandled exception at 0x0051a1e0 in clash.exe: 0xC0000005: Access violation reading location 0xffffffff.

(or reading location 0x00000000 +/- small delta) is indicitive of accessing memory by way of an uninitialized pointer. Set the Debugger runtime options to trap on access of uninitialized variables.
My guess is you did not initialize something in Strucad_Binary_Model. I see a reference to iNoFitLoaded without seeing one time initialization of it. Are you assuming initialization is being performed when you are required to explicitly perform initialization?
Jim Dempsey
0 Kudos
jim_dempsey
Beginner
1,048 Views

Also in looking at the Fortran Language Reference you will find that the integer arguments are integer(4) not integer(2) for Win32 and integer(8) for Win64.

integer*2, dimension(iMAXNOCHKFIT) :: iFitStkPtr
integer (SIZEOF_SIZE_T) iArrayLen,iElementSize
...

call qsort(iFitStkPtr,iArrayLen,iElementSize,fnCompareFitStk)

iFitStkPtr is definately incorrect, the information you supplied does not indicate the value of SIZEOF_SIZE_T. Must be 4 for IVF on Win32 and all integer variables must be 8 on Win64.

Jim Dempsey

0 Kudos
lesneilson
Beginner
1,048 Views

Doh,

You are right. I totally missed the fact that iFitStkPtr is integer*2

Talk about can't see the wood for the trees!

Thanks

Les

0 Kudos
lesneilson
Beginner
1,048 Views

On second thoughts. From the Fortran help :

CALL QSORT (array, len, isize, compar)

array
(Input) Any type. One-dimensional array to be sorted.

So integer*2 iFitStkPtr is acceptable.
In fact the example given in the help uses an integer*2 array also.
wrt your other comments/suggestions :-
iNoFitLoaded is initialised to zero at the start of the exe.
iArrayLen and iElementSize are both integer*4 (I also tried the SIZEOF_SIZE_T from the help example) iElementSize is set to 2 before call to qsort.
I set all runtime debug options on but none were reported before or afterthe exception.
Running in debug mode I set a breakpoint just before the call to qsort and another in the compare function. At the first breakpoint all the appropriate variables had correct values. Stepping into the compare function again all the variables had correct values. Only when exiting the function (back to qsort) did the exception occur.
As I said I have replaced the call to qsort with one of our own routines so I have a workaround, but I am curious whether qsort has a problem with COMMON arrays
Les
0 Kudos
Reply