|
From: Gib Bogle on 6 May 2008 00:01 I am still trying to get to grips with how one should copy derived types that contain allocatable arrays. The test program below, when compiled with IVF 10.1, displays the cdata array contents correctly, but gives an access violation in the deallocation step. If I neglect the deallocation there are no error messages. When compiled on IBM Linux (with xlf95_r) it runs without errors. But running my real program, in which I am presumably doing something wrong, on the IBM machine there is no error until the deallocation step, which is carried out exactly as in the code below, and then I get a multitude of error messages like glibc detected *** double free or corruption (!prev): 0x100a0220 and glibc detected *** corrupted double-linked list: 0x1009db18 Is it OK to do cell2(i) = cell1(i) when cell2(i)%cdata has not been allocated, or do I first need to ensure that %cdata is allocated? !---------------------------------------------------------------- program main integer :: csize(2) = (/10,100/) integer :: k, i type cell_type integer :: ID real, allocatable :: cdata(:) end type type(cell_type), allocatable :: cell1(:),cell2(:) allocate(cell1(2)) allocate(cell2(2)) do i = 1,2 allocate(cell1(i)%cdata(csize(i))) do k = 1,csize(i) cell1(i)%cdata(k) = k enddo enddo do i = 1,2 cell2(i) = cell1(i) ! cell2(i)%cdata not allocated write(*,*) cell2(i)%cdata enddo do i = 1,2 do k = 1,csize(i) if (allocated(cell1(i)%cdata)) then deallocate(cell1(i)%cdata) endif enddo if (allocated(cell1)) then deallocate(cell1) endif enddo do i = 1,2 do k = 1,csize(i) if (allocated(cell2(i)%cdata)) then deallocate(cell2(i)%cdata) endif enddo if (allocated(cell2)) then deallocate(cell2) endif enddo end ------------ And now a word from our sponsor ------------------ Want to have instant messaging, and chat rooms, and discussion groups for your local users or business, you need dbabble! -- See http://netwinsite.com/sponsor/sponsor_dbabble.htm ----
From: Gib Bogle on 6 May 2008 02:09 I must be more tired than I thought. The code I posted previously is obviously wrong, in a couple of embarrassing ways, and the reason for the access violation is clear. What I meant to do is shown below. This code executes fine. I thought I was on the scent of the bug in my real program, but I was confused. The interesting thing (to me) here is that the assignment cell2(i) = cell1(i) has the effect of allocating cell2(i)%cdata. Should this be obvious? program main integer :: csize(2) = (/10,100/) integer :: k, i type cell_type integer :: ID real, allocatable :: cdata(:) end type type(cell_type), allocatable :: cell1(:),cell2(:) allocate(cell1(2)) allocate(cell2(2)) do i = 1,2 allocate(cell1(i)%cdata(csize(i))) do k = 1,csize(i) cell1(i)%cdata(k) = k enddo enddo do i = 1,2 cell2(i) = cell1(i) ! cell2(i)%cdata not allocated before this write(*,*) cell2(i)%cdata enddo do i = 1,2 if (allocated(cell1(i)%cdata)) then deallocate(cell1(i)%cdata) endif enddo if (allocated(cell1)) then deallocate(cell1) endif do i = 1,2 if (allocated(cell2(i)%cdata)) then write(*,*) 'deallocate cell2(i)%cdata: ',i deallocate(cell2(i)%cdata) endif enddo if (allocated(cell2)) then deallocate(cell2) endif end
From: James Van Buskirk on 6 May 2008 02:11 "Gib Bogle" <g.bogle(a)auckland.no.spam.ac.nz> wrote in message news:481fd818$1(a)news.auckland.ac.nz... > do i = 1,2 > do k = 1,csize(i) > if (allocated(cell1(i)%cdata)) then > deallocate(cell1(i)%cdata) > endif > enddo > if (allocated(cell1)) then > deallocate(cell1) > endif > enddo Your problems start at the above loop. Consider that for each value of i, there is only one cell1(i)*cdata array. Now you are contemplating deallocating this array 10 or 100 times in the k loop, but you are saved by the fact that you check for allocation status before deallocating. You are not so lucky regarding the consequences of deallocation of cell1 later in the loop, however. Consider that on the first trip through the i loop, cell1 was allocated, so you checked this, then deallocated it. On the second trip through the i loop, your program should die when you check whether cell1(i)%cdata is allocated because there is no cell1(i)%cdata because there is no cell1(i) because you deallocated cell1 on the first trip through the loop. You might more easily have replaced the whole i loop with: if(allocated(cell1)) deallocate(cell1) Because that automatically deallocates its allocatable components. > do i = 1,2 > do k = 1,csize(i) > if (allocated(cell2(i)%cdata)) then > deallocate(cell2(i)%cdata) > endif > enddo > if (allocated(cell2)) then > deallocate(cell2) > endif > enddo See comments for other deallocation loop. -- write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, & 6.0134700243160014d-154/),(/'x'/)); end
From: Gib Bogle on 6 May 2008 02:39 Please forgive me for responding to my own posts. I made csize big: csize(2) = (/1000000,100000000/), put a do loop around the whole program, and experimented with allocating/not allocating cell2(i)%cdata in advance of assigning values to it. I have convinced myself that there is no memory leakage. It seems that when the derived-type variables cell2(i) and cell1(i) are equated the allocatable component cell2(i)%cdata is allocated if not previously allocated, and if it was already allocated it is effectively resized and any unused memory is deallocated. In other words the compiler does what you'd want it to do. Probably everyone else already knew this. ------------ And now a word from our sponsor --------------------- For a secure high performance FTP using SSL/TLS encryption upgrade to SurgeFTP ---- See http://netwinsite.com/sponsor/sponsor_surgeftp.htm ----
From: James Van Buskirk on 6 May 2008 02:41 "Gib Bogle" <g.bogle(a)auckland.no.spam.ac.nz> wrote in message news:481ff61f$1(a)news.auckland.ac.nz... > was confused. The interesting thing (to me) here is that the assignment > cell2(i) = cell1(i) has the effect of allocating cell2(i)%cdata. Should > this be obvious? Yes, that's the way allocatable components are supposed to work. In fact, you could have simply said: cell2 = cell1 and cell2 would have been reallocated to the same shape as cell1 and the the components of each element of the cell2 array would have been allocated if necessary. WARNING: you said earlier that you were ifort 10.1. This compiler does not behave in a standard way when assignments to whole allocatable arrays are carried out, unless you use some switch at compile time. Check the ifort documentation carefully for the exact nature of its behavior. It's not standard without the switch. -- write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, & 6.0134700243160014d-154/),(/'x'/)); end
|
Next
|
Last
Pages: 1 2 Prev: weird g77 and gfortran Next: Graphical representation of f90/f95 programs |