- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dear Forum,
I'm having trouble figuring out how to properly allocate my defined type in a subroutine and return the data to the main program using a structure pointer passed to the subroutine. I suspect I am making an easy mistake but I can't find the right way to set this up and help would be greatly appreciated.
compiled, version 18.0.1.156 Build 20171018:
ifort datTest.f90
On execute I get: "forrtl: severe (157): Program Exception - access violation" as soon as I try to access structure.
Test code, datTest.f90, below.
Thanks!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@keller, scott,
Note the two allocated objects in your two subroutines, getDataPtr and getDataObject, are "local" to those procedures and when the execution returns from those subprograms, those objects can get destroyed. If you intended for your "mydata" objects to be "global: objects instead with "saved" status, you may consider explicit instructions for the same by placing them in your MODULE itself i.e., before the CONTAINS section:
module Test implicit none type myArrObj real , allocatable, dimension(:) :: dat end type myArrObj ! Declare "global" objects that are saved real, allocatable, target, save :: mydata1(:) type(myArrObj), target, save :: mydata2 contains subroutine getDataPtr(dPtr) real, pointer , dimension(:) , intent(out)::dPtr allocate(mydata1(10)) mydata1 = 7.0 dPtr => mydata1 return end subroutine getDataPtr subroutine getDataObject(dPtr) type(myArrObj), pointer, intent(out)::dPtr allocate(mydata2%dat(10)) mydata2%dat = 5.0 dPtr => mydata2 print *, dPtr%dat ! Allocation happend and data is here return end subroutine getDataObject end module Test program datTest use Test type(myArrObj), pointer :: ObjPtr => null() real, pointer, dimension(:) :: ArrayPtr => null() call getDataPtr(ArrayPtr) print *, ArrayPtr ! Allocation done in subroutine and data returns w pointer call getDataObject(ObjPtr) print *, ObjPtr%dat ! forrtl: severe (157): Program Exception - access violation end program datTest
Separately, you may want to consider moving away from POINTER attribute and work with ALLOCATABLE attribute in Fortran and move away from "globally" saved objects and rather have data in objects allocated in the calling code and given your use of OO-like getter procedures, perhaps you may want to look into OO features in Fortran and employ them instead. The references in this Dr Fortran blog can be helpful for details: https://software.intel.com/en-us/blogs/2013/12/30/doctor-fortran-in-its-a-modern-fortran-world
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@keller, scott,
Note the two allocated objects in your two subroutines, getDataPtr and getDataObject, are "local" to those procedures and when the execution returns from those subprograms, those objects can get destroyed. If you intended for your "mydata" objects to be "global: objects instead with "saved" status, you may consider explicit instructions for the same by placing them in your MODULE itself i.e., before the CONTAINS section:
module Test implicit none type myArrObj real , allocatable, dimension(:) :: dat end type myArrObj ! Declare "global" objects that are saved real, allocatable, target, save :: mydata1(:) type(myArrObj), target, save :: mydata2 contains subroutine getDataPtr(dPtr) real, pointer , dimension(:) , intent(out)::dPtr allocate(mydata1(10)) mydata1 = 7.0 dPtr => mydata1 return end subroutine getDataPtr subroutine getDataObject(dPtr) type(myArrObj), pointer, intent(out)::dPtr allocate(mydata2%dat(10)) mydata2%dat = 5.0 dPtr => mydata2 print *, dPtr%dat ! Allocation happend and data is here return end subroutine getDataObject end module Test program datTest use Test type(myArrObj), pointer :: ObjPtr => null() real, pointer, dimension(:) :: ArrayPtr => null() call getDataPtr(ArrayPtr) print *, ArrayPtr ! Allocation done in subroutine and data returns w pointer call getDataObject(ObjPtr) print *, ObjPtr%dat ! forrtl: severe (157): Program Exception - access violation end program datTest
Separately, you may want to consider moving away from POINTER attribute and work with ALLOCATABLE attribute in Fortran and move away from "globally" saved objects and rather have data in objects allocated in the calling code and given your use of OO-like getter procedures, perhaps you may want to look into OO features in Fortran and employ them instead. The references in this Dr Fortran blog can be helpful for details: https://software.intel.com/en-us/blogs/2013/12/30/doctor-fortran-in-its-a-modern-fortran-world
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@FortranFan: Thanks so much for your post, it helped me understand the deallocate behavior in the subroutine better and your comments pointed me in the direction I was looking for. It was even easier to do what I was hoping. I'm attaching the modified version in case anyone else is interested in the same issue.

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page