- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I use this subroutine to add a new segment object to array of segments (sarArray):
subroutine segArrayAddNewMember(sarArray, segNewMember) use class_segment implicit none type(segment), dimension(:), allocatable, & intent(inout) :: sarArray type(segment), intent(in) :: segNewMember type(segment), dimension(:), allocatable :: sarTemp integer intSize if (allocated(sarArray)) then intSize = size(sarArray) allocate(sarTemp(intSize+1)) sarTemp(1:intSize) = sarArray sarTemp(intSize+1) = segNewMember deallocate(sarArray) call move_alloc(sarTemp, sarArray) else allocate(sarArray(1)) sarArray(1) = segNewMember end if end subroutine segArrayAddNewMember
However the problem is all of the pointers to existing members become corrupted and the only thing I can think of is the deallocate/moveallocate is causing it.
Is it possible to prevent corruption of pointers?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I'm not sure what the standard says, but I would definitely not count on pointers to sarArray elements being safe after it has been deallocated and reallocated. The only way to fix this is to make sarArray a linked list rather than an allocatable array. Then you can add/remove elements without changing the existing ones. If you want to keep the allocatable array, you'd have to include a mechanism for reassociating the pointers to the new elements after it is resized, if that is possible in your case.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I'm not sure what the standard says, but I would definitely not count on pointers to sarArray elements being safe after it has been deallocated and reallocated. The only way to fix this is to make sarArray a linked list rather than an allocatable array. Then you can add/remove elements without changing the existing ones. If you want to keep the allocatable array, you'd have to include a mechanism for reassociating the pointers to the new elements after it is resized, if that is possible in your case.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Once you deallocate the array, any pointers to the array or its elements become undefined. Indeed it is certain, given the code above, that the new array will be at different locations than the old array.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Would giving sarArray the TARGET attribute help, or would that at least indicate an error?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
In addition (maybe irrelevant), are you sure the doing a reallocate to increase the size by 1 is a great idea? If the array is growing that could be really slow. Maybe increasing by a fixed proportion e.g +30% might be better and then downsizing to the final size when it has stopped growing if you want to save the memory
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
S. PMay wrote:
.. Is it possible to prevent corruption of pointers?
@S. PMay,
Note the Fortran standard essentially places all the responsibility on the coder in situations such as the one in your original post. You may take note of the following:
- AVOID components in derived types ('classes') with POINTER attribute; adopt the ALLOCATABLE attribute instead
- if avoidance of POINTER components is not feasible, implement DEFINED assignments in all the derived types that control deep vs shallow copy of the components. Also implement FINAL procedure bindings ('finalizers') with the necessary cleanup steps for the components with the POINTER attribute.
- If you still notice issues after following the suggestions in point #2, create fully reproducible examples and submit support requests at the Intel OSC: https://supporttickets.intel.com/?lang=en-US
By the way, note the DEALLOCATE statement on line 15 in the code in the original post is superfluous; MOVE_ALLOC on the following line is all you need.
Separately you may want to review this thread in detail: https://software.intel.com/en-us/forums/intel-visual-fortran-compiler-for-windows/topic/701985
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
John Campbell wrote:
Would giving sarArray the TARGET attribute help, or would that at least indicate an error?
No, this would not have any useful effect.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
andrew_4619 wrote:
In addition (maybe irrelevant), are you sure the doing a reallocate to increase the size by 1 is a great idea? If the array is growing that could be really slow. Maybe increasing by a fixed proportion e.g +30% might be better and then downsizing to the final size when it has stopped growing if you want to save the memory
Thanks for the tip, performance is not an issue here. This routine is only run until input file is over.
FortranFan wrote:
Note the Fortran standard essentially places all the responsibility on the coder [...]
- AVOID components in derived types ('classes') with POINTER attribute; adopt the ALLOCATABLE attribute instead
- if [...] not feasible, implement DEFINED assignments[...]. Also implement FINAL [...] with the necessary cleanup steps [...]
- If you still notice issues[...],submit support requests at the Intel OSC[...]
By the way, note the DEALLOCATE statement on line 15 in the code in the original post is superfluous; [...]
Separately you may want to review this thread in detail: https://software.intel.com/en-us/forums/intel-visual-fortran-compiler-fo...
Thanks for very useful comments. all I want is same instance of objects:
segment objects create elements, one segment can belong to two elements. what happens to one segment should affect both elements.
using pointers was my solution. so each element have segment pointer that points to the corresponding segment object in segments array (sarSegments).
Using pointers is the only solution I can think of. In most other OOP languages the class objects are automatically same instance I think.

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