- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi, I am using legacy fortran code and it seems that TYPE structures are copied in many places using the scheme struct1=struct2. Then pointers are deallocated from struct1 (which are really pointers or copies of pointers of struct2). My question is, is struct1 copied I would think it is just pointed to struct2. This scheme has worked for many years but when calling the fortran dll from c#, i many times seems to get a Attempted to Read or Write Protected Memory error. Any help or advice is appreciated.
Jeremy
Maybe this isnt the best explanation so i'll include the code:
module display
use picturedata
type (picture), SAVE :: pic(50), pictemp
...
end module display
module picturedata
use bitmaptypes
type picture
integer nx,ny
real*4,pointer :: array(:,:)=>Null()
...
end
Then, the project will use display. Creating pic(2)%array, pic(2)%nx ... and calling pic(1)=pic(2), this seems to copy the structure to pic(1) and then pic(1)%array is deallocated and allocated. This seems to work with the legacy code, but when calling from c# i get the accessing proctected memory.
Jeremy
Maybe this isnt the best explanation so i'll include the code:
module display
use picturedata
type (picture), SAVE :: pic(50), pictemp
...
end module display
module picturedata
use bitmaptypes
type picture
integer nx,ny
real*4,pointer :: array(:,:)=>Null()
...
end
Then, the project will use display. Creating pic(2)%array, pic(2)%nx ... and calling pic(1)=pic(2), this seems to copy the structure to pic(1) and then pic(1)%array is deallocated and allocated. This seems to work with the legacy code, but when calling from c# i get the accessing proctected memory.
Link Copied
18 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
If you assign a derived type (structure), pointers are simply copied - there is no deallocation/reallocation. However, ALLOCATABLE arrays have the data copied, with the left side being (re) allocated to the proper shape if required.
So, if you copy a structure with pointers, and then deallocate the pointers in one, the pointers in the other are no longer defined. This doesn't mean they are zeroed - it simply means that you are not allowed to reference them.
So, if you copy a structure with pointers, and then deallocate the pointers in one, the pointers in the other are no longer defined. This doesn't mean they are zeroed - it simply means that you are not allowed to reference them.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Quoting - Steve Lionel (Intel)
If you assign a derived type (structure), pointers are simply copied - there is no deallocation/reallocation. However, ALLOCATABLE arrays have the data copied, with the left side being (re) allocated to the proper shape if required.
So, if you copy a structure with pointers, and then deallocate the pointers in one, the pointers in the other are no longer defined. This doesn't mean they are zeroed - it simply means that you are not allowed to reference them.
So, if you copy a structure with pointers, and then deallocate the pointers in one, the pointers in the other are no longer defined. This doesn't mean they are zeroed - it simply means that you are not allowed to reference them.
What doesnt make sense to me is if you call pic(1)=pic(2) and then deallocate(pic(1)%array), the array of pic two (pic(2)%array) still exists.
Finally why does this work as a fortran executible, but crashes when run as a c# dll?
Thanks a lot. Jeremy
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
No, I didn't say that. When you write pic(1)=pic(2), each member of pic(2) gets copied to the corresponding member of pic(1). Since one of those members is a pointer, the pointer gets copied as well.
In the situation you describe, pic(2)%array is a pointer to deallocated storage. It may seem to "exist", but it is an error to try to reference it and that storage may end up being used for something else.
If you are referencing through undefined pointers, all bets are off.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks Steve
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Actually i had one last question, according to my example above, if i simply allocate pic(2)%array and with an assignment pic(2)%array=pic(1)%array, will that copy the array or will the pointer by pointed to pic(1),thanks
Jeremy
Jeremy
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
That will copy the data, not the pointer.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Quoting - Steve Lionel (Intel)
That will copy the data, not the pointer.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Quoting - jjfait
Is there a special case with multi-dimensional arrays? I specifically deallocate (if associated) and allocate pic(2)%array to the size of pic1 and then set pic(2)%array=pic(1)%array to copy the array and i get a stack overflow error??? Is there an error because i'm using two dim. arrays. thanks
It's a special case with derived types. As soon as the arrays in an arrays assignment are components of a derived type, the Intel compiler always creates a temporary (see this thread: http://software.intel.com/en-us/forums/showthread.php?t=66011).
You can use the compiler option -heap-arrays to get rid of the stack overflow, but of course the temporary is still created. If you want to avoid this because it uses more memory and is slower, you can use DO-loops to copy the array.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks Tom, that has solved this problem, but i have another one that is very confusing. Maybe i should move this one to a new thread. I took everything out of the subroutine because something has operating incorrectly. This code has the "=" operator overloaded to call a subroutine below inside of module display:
interface assignment(=)
subroutine picture_to_picture(outpic,inpic)
use picturemod
type (picture),intent(inout)::outpic
type (picture),intent(in)::inpic
end subroutine picture_to_picture
end interface
subroutine picture_to_picture(outpic,inpic)
use picturemod
implicit none
type (picture),intent(inout):: outpic
type (picture),intent(in):: inpic
integer shape2(2)
integer shape1(1),i,j
write(11,*)'in pic to pic'
end subroutine picture_to_picture
As you can see this function does nothing but print that it came in. Now when i call for a picture to be = to another it works everytime except for the certain case pic(3) = pictemp. With any pic number, ex pic(1),pic(2),...
pic(15)=pic(10)
pic(4)=pic(2)
pictemp=pic(3)
pic(20)=pic(1)
pic(3)=pictemp
pic(20)=pic(1)
Now all of these work except the line pic(3)=pictemp, and it always gives a stack overflow error at that line if i move it around. These are both of thetype (picture).It doesn't give an error if i use the compiler option -heap-arrays, but that seem like it would solve the problem. This make absolutely no sense to me.
interface assignment(=)
subroutine picture_to_picture(outpic,inpic)
use picturemod
type (picture),intent(inout)::outpic
type (picture),intent(in)::inpic
end subroutine picture_to_picture
end interface
subroutine picture_to_picture(outpic,inpic)
use picturemod
implicit none
type (picture),intent(inout):: outpic
type (picture),intent(in):: inpic
integer shape2(2)
integer shape1(1),i,j
write(11,*)'in pic to pic'
end subroutine picture_to_picture
As you can see this function does nothing but print that it came in. Now when i call for a picture to be = to another it works everytime except for the certain case pic(3) = pictemp. With any pic number, ex pic(1),pic(2),...
pic(15)=pic(10)
pic(4)=pic(2)
pictemp=pic(3)
pic(20)=pic(1)
pic(3)=pictemp
pic(20)=pic(1)
Now all of these work except the line pic(3)=pictemp, and it always gives a stack overflow error at that line if i move it around. These are both of thetype (picture).It doesn't give an error if i use the compiler option -heap-arrays, but that seem like it would solve the problem. This make absolutely no sense to me.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
This type of operation must not be very well supported because i found another error in the compiler. Say you call the code below:
subroutine crash()
use display
implicit none
integer i
pic(15)=pic(10)
end
This will result in :Error: This is either an invalid statement, a declaration statement that is ordered incorrectly, or a null procedure statement. This will happen if this is the first line of the subroutine. If you put a line in front of it say, i=2, then it will compile fine. I no longer trust the functionality of overloading the "=" operator and think i'll have to change it everywhere in the code.
subroutine crash()
use display
implicit none
integer i
pic(15)=pic(10)
end
This will result in :Error: This is either an invalid statement, a declaration statement that is ordered incorrectly, or a null procedure statement. This will happen if this is the first line of the subroutine. If you put a line in front of it say, i=2, then it will compile fine. I no longer trust the functionality of overloading the "=" operator and think i'll have to change it everywhere in the code.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Where is "pic" declared? I think you have an error in the code - the compiler thinks that "pic" is a function as it is not declared as an array.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Quoting - Steve Lionel (Intel)
Where is "pic" declared? I think you have an error in the code - the compiler thinks that "pic" is a function as it is not declared as an array.
use picturedata
type (picture), SAVE :: pic(50), pictemp
end module display
module picturedata
type picture
integer nx,ny ....
real*4,pointer :: array(:,:)=>Null()
end
So pic is a derived type that has already has been filled in and if called as the first line of the subroutine iget a compiler error but called as the second line it's fine, doesn't make sense. Also if i use pic(number)=pictemp, many times i get a stack overflow error, but i can call pic(num)=pic(num) or pictemp=pic(num) without the error, also doesn't make sense.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Please provide a short (if possible) but complete source that demonstrates the problem. Paraphrases are often missing some key element.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Sure, if you try to make a project and compile this you will get an error as described above:
module display
use picturemod
type (picture), SAVE :: pic(50), pictemp
interface assignment(=)
subroutine picture_to_picture2(outpic,inpic)
use picturemod
type (picture),intent(inout)::outpic
type (picture),intent(in)::inpic
end subroutine picture_to_picture2
end interface
end module display
module picturemod
type picture
integer nx,ny !array bounds of array coords
real*4,pointer :: array(:,:)=>Null()
end type picture
end module picturemod
subroutine picture_to_picture2(outpic,inpic)
use picturemod
implicit none
type (picture),intent(inout):: outpic
type (picture),intent(in):: inpic
write(11,*)'in pic to pic2'
end subroutine picture_to_picture2
subroutine crash()
use display
implicit none
integer i
pic(15)=pic(10)
end
program Main
use display
end
I cannot redisplay the error of pic(num)=pictemp though, because the stack exceptionoccurs at random times in my program
module display
use picturemod
type (picture), SAVE :: pic(50), pictemp
interface assignment(=)
subroutine picture_to_picture2(outpic,inpic)
use picturemod
type (picture),intent(inout)::outpic
type (picture),intent(in)::inpic
end subroutine picture_to_picture2
end interface
end module display
module picturemod
type picture
integer nx,ny !array bounds of array coords
real*4,pointer :: array(:,:)=>Null()
end type picture
end module picturemod
subroutine picture_to_picture2(outpic,inpic)
use picturemod
implicit none
type (picture),intent(inout):: outpic
type (picture),intent(in):: inpic
write(11,*)'in pic to pic2'
end subroutine picture_to_picture2
subroutine crash()
use display
implicit none
integer i
pic(15)=pic(10)
end
program Main
use display
end
I cannot redisplay the error of pic(num)=pictemp though, because the stack exceptionoccurs at random times in my program
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You had talked about an "invalid declaration" error - can you show me that?
You may want to enable the /heap-arrays option. In Visual Studio, set it to a value of 0.
You may want to enable the /heap-arrays option. In Visual Studio, set it to a value of 0.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Quoting - Steve Lionel (Intel)
You had talked about an "invalid declaration" error - can you show me that?
You may want to enable the /heap-arrays option. In Visual Studio, set it to a value of 0.
You may want to enable the /heap-arrays option. In Visual Studio, set it to a value of 0.
I can put in that option but it seems like its avoiding the real problem why there is a stack overflow when using the "=" to call an empty subroutine.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Ok - I can see the syntax error. Looks as if the compiler thinks this is a statement function, but it isn't. I'll report it to the developers. Issue ID is DPD200140044. Adding a CONTINUE statement before the assignment is a workaround.
I don't see the stack overflow when I run this code.
I don't see the stack overflow when I run this code.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The syntax error is fixed in the compiler - I expect the fix to appear in 11.1 Update 5, scheduled for mid-February.

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