Error deallocating variable declared in module - fortran

I'm having an issue with my Fortran 90 code involving deallocating an array that is declared in a module and then allocated & initialized within a subroutine. Within my program, I declare a bunch of arrays in modules like real*8, dimension(:), allocatable :: test. Then, in an initialization subroutine, I use the module, allocate the variable with
allocate(test(8)), and initialize it with test = 0.d0.
After this, I can print*, test and get the appropriate output: 0.E+0 0.E+0 0.E+0 0.E+0 0.E+0 0.E+0 0.E+0 0.E+0. In addition, a call to allocated(test) returns .TRUE.. Nevertheless, something goes wrong. Directly after the call to allocate(), a call to sizeof(test) returns 0 and a call to deallocate(test) throws the following error:
lib-4422 : UNRECOVERABLE library error
A DEALLOCATE statement argument points to a portion of the
original allocation.
Original size in bytes for the argument is 512
Current size in bytes for the argument is 0
Segmentation fault
This all occurs within a larger code, throughout which I've used these arrays with no errors. I only noticed the problem when I tried to deallocate the memory at the end of the program while hunting for a memory leak. I've tried to make a simple program that only does what has been described above (i.e., declare in module, allocate & initialize in subroutine, then print the array and deallocate it within the same subroutine). This simple code, however, works properly and runs without error. Thus, I'm very confused at what could be causing this to misbehave within the context of the larger code. Furthermore, if within my larger code I move the declaration line from the module to the subroutine, everything runs properly.
Any advice would be appreciated! Thanks in advance,
~BCL

When dealing with arrays that are not internal to a single subroutine, I always use the pointer attribute when declaring them instead of the attribute. In practice both will work the same. For example:
module Mod1
contains
subroutine sub1(Array)
!*** Declaration of Variables
implicit none
!*** External Variables - Arguments
real(kind=8), pointer, intent(inout) :: Array(:)
!*** Internal Variables
real(kind=8), allocatable :: InternalArr(:)
!*** Memory allocation
allocate(Array(1:8))
allocate(InternalArr(9:10))
!*** End of Subroutine
end subroutine sub1
end module Mod1
Once you call sub1, your array will keep its dimensions at any place of your code. You can deallocate and allocate it as much as you need.
Before using pointer I suffered some issues like the one you described and someone suggested me to use pointer instead. Since then, I've become very used to declare arrays this way (if they are meant to remain on the same subroutine or module I keep using allocatable) and it has always shown to be a good way to keep arrays under control.
I really hope this helps... It is my very first answer :)
EDIT: I corrected a little error on the example code

Related

Global/ module variables versus local variables in fortran

I am pretty new to programming and using fortran 90 to write a cfd solver that takes a while to run. I am using a module and derived types to store global variables which are used in subroutines in a large do-loop in my main program. I have noticed that if I am referencing one of these global variables and don't need to alter its value, it is slower to use the variable defined in the module than to create a local variable within the subroutine. For instance, I have a type called grd with a real constant A stored in it. Instead of referencing grd%A over and over in a subroutine, it seems to be faster if I create a local A within the subroutine and assign it upfront, A=grd%A, and use A instead. I've run speed tests and for my particular program and defining this local A gives me about a 10% increase in speed, which ends up being pretty significant.
Can anyone explain why this would be the case? Are local variables always faster? Thanks!

Returning static/ normal arrays in recursion/another function

A non-static array is declared in one function, it is returned and stored in another non-static array in main.
Q 1> I know that when an array is passed, it is passed by pointer(not by reference) so any changes made to the array in the passed function gets reflected in the original function but in this case while returning that array to another function say main shouldn't the original array be destroyed when it goes out of it's function scope?
Static variable retain value within function calls and it's lifetime is the entire program so it is justified for a static array but why so for a non static array?
Q 2>Now say we have a non-static array declared inside a function that undergoes recursion, does the array gets declared each time it recurses? It doesn't goes out of the scope so the array is re-declared so why doesn't it gives a redeclaration error? Is it a new array or does the array gets over-written?
Say we have a static array now, it being a static it is declared only once..
Does changes made in the array in one recursion gets reflected in another recursion if the array is static/non static?
I tried it out and I got that for non static arrays changes are not reflected but in static arrays the changes are reflected so again it basically boils down to the first question?
Q 3> Say we declared a static array and we run two tests(one imp thing to mention is we need the values we get in the previous recursion for the next recursion), the arrays values stored in the first test case(it being static) leads to incorrect values stored during the second test case run(well consider it as a vector so it will give incorrect output when we push the elements in second run since the values stored in the first run are already in the vector). Can you suggest a way to get around this w/o removing the static array
I know I have asked many questions all together at the same time, but I did that because they are all related 1 and 2 more so. 3 will help me clear my doubts better. It will be very helpful if you can clear the doubts. Thank You
Q 1> I know that when an array is passed, it is passed by pointer(not by reference) so any changes made to the array in the passed function gets reflected in the original function but in this case while returning that array to another function say main shouldn't the original array be destroyed when it goes out of it's function scope?
Yes, the array will be destroyed when the function it's declared in exits. If you continue trying to use it after that point, you'll get "undefined behaviour" - which means that anything could happen. It might seem to work, it might crash, or it might contain garbage data.
Q 2>Now say we have a non-static array declared inside a function that undergoes recursion, does the array gets declared each time it recurses? It doesn't goes out of the scope so the array is re-declared so why doesn't it gives a redeclaration error? Is it a new array or does the array gets over-written?
It's a new array. Each call to a function gets its own copy of that function's local variables.
Q 3> Say we declared a static array and we run two tests(one imp thing to mention is we need the values we get in the previous recursion for the next recursion), the arrays values stored in the first test case(it being static) leads to incorrect values stored during the second test case run(well consider it as a vector so it will give incorrect output when we push the elements in second run since the values stored in the first run are already in the vector). Can you suggest a way to get around this w/o removing the static array
You could make it global, then clear it between tests. That's not the prettiest solution, but it's probably the easiest.

c++ force array declaration without giving parameters

I'm currently trying to program an array of objects in a c++ program. However it keeps giving me errors when trying to create the arrays.
So on top of my code I have the following code:
#define sensNumber 4
ros::Publisher pub_range2 [sensNumber];
this gives the error:
multisone2.ino:19:38: error: no matching function for call to ‘ros::Publisher::Publisher()’
So it's trying to call the constructor for Publisher, why? And how do I stop it?
Now I know this can also be done with Vectors but I'm trying to optimize the code esp. for reading speed so I would rather avoid vectors(yes I know that it remains linair but accessing this array represents a significant portion of my code).
As you're trying to stack-allocate sensNumber instances of ros::Publisher, the default constructor must be called.
An alternative would be to allocate an array of pointers to ros::Publisher. Better still, an array of std::unique_ptr or std::shared_ptr.
When you declare an array of c++ objects you're actually instantiating each element. This means that the default parameterless constructor is called for each array element. If you don't want to instantiate all elements when declaring your array, you should declare an array of pointers instead and then initialize each element whenever required.

Cost of using functions in fortran (or any other language)

Let say I have a array which is very big verybigvariable
And I have defined a function that does some operations like this
function myfunc(var) result(res)
real:: var(:,:,:),res
...
...
...
end function myfunc
My question is that when I call this function like this
myvar=myfunc(verybigvariable)
what happens? does it duplicate my variable so it holds 2X space in the ram during the execution of the function? If so how can I prevent this? (In a simple program, I know, I can define the function without any parameter and make it use existing variables, but If I am programming a module, it seems I have to include parameter to the definition)
The Fortran language standard does not specify how arguments are passed. Typically in the interest of efficiency the compiler will not make a copy but pass the address of the argument. There will be cases in which a Fortran compiler has to make a copy. E.g., the actual argument is a non-contiguous array but the procedure expects a contiguous argument. The compiler will have to fix the mismatch by making a copy that is contiguous to pass to the procedure. If the procedure modifies that argument, the values have to be copied back to the original argument.
In fortran it seems that parameters are passed by reference. This means that only the address of the variable is passed, and the function can then access the variable through that address.
So no, the array is not copied, only the address of the array is passed. The overhead for this will be either 32 bits for a 32-bit system, or 64 bits for a 64-bit system.
I have no experience with fortran, and this is only what I could figure out though a Google search, so if any Fortran programmers have any remarks, please feel free to edit/comment.

How do I trace a potential undefined behavior situation?

I get a double free error on deallocate, when the pointer is associated. I suspect some undefined behavior is ongoing, but I have no idea where to start looking for it, or how. How do you track down undefined behavior ?
The compiler is intel 12. I can't post code because it's huge, and I am not even sure the source of problem is in my code. It may be in a colleague's library. I tried to do some debugging with gdb, but I don't get very far. This is the error.
malloc: * error for object 0x102302f20: pointer being freed was not allocated
* set a breakpoint in malloc_error_break to debug
The line immediately before that is a print *, associated(pointer), which prints true.
This is the backtrace
#0 0x00007fff9327b6c0 in malloc_error_break ()
#1 0x00007fff9327b805 in free ()
#2 0x0000000100d27470 in for_dealloc_allocatable ()
#3 0x0000000100506699 in sharedarraysmodule_mp_deleterealsharedarray2_ () at SharedArrays.f90:609
#4 0x00000001003bbc4e in gammaaggregatormodule_mp_deleteprivate_ () at GammaAggregator.f90:86
#5 0x0000000102300bc0 in ?? ()
Previous frame inner to this frame (gdb could not unwind past this frame)
Long comment, might point (sorry, couldn't resist) towards an answer ...
To be pedantic, it looks as if your compiler's best guess is 'pointer being freed was not allocated'. But in Fortran pointers only have statuses undefined, associated and disassociated so the error message may arise out of calls to the system functions which the compiler links into your executable.
That being said, I'd look for:
A target going out of scope while a pointer to it remains in scope. The Fortran 2003 standard states (note 16.13)
A pointer from a module program unit may be accessible in a subprogram via use association.
Such pointers have a lifetime that is greater than targets that are declared in the subprogram,
unless such targets are saved. Therefore, if such a pointer is associated with a local target, there is
the possibility that when a procedure defined by the subprogram completes execution, the target
will cease to exist, leaving the pointer “dangling”. This standard considers such pointers to have
an undefined association status. They are neither associated nor disassociated. They shall not be
used again in the program until their status has been reestablished. There is no requirement on a
processor to be able to detect when a pointer target ceases to exist.
The same document also states that the association status of the pointer passed to the associated intrinsic shall not be undefined so it's probably allowable for the program to lie and tell you that associated(undefined_pointer)==.true..
An allocatable target being deallocated, either by going out of scope or as a result of a deallocate() call.
Pointers being nullified on declaration, eg real, pointer :: rptr => null() (this is generally held to be a good thing, you might look to ensure that your code conforms).
Pointers being nullified before they have been associated, though I don't think that nullifying a null pointer is an error according to the standard.
Pointers to pointers.
The error messages you report tend to suggest that you have a case of module variables going out of scope, but, as you've already observed, it's kind of difficult to be certain.
If this doesn't help, contact Intel tech support, I find them very helpful, they are pretty good at spotting problems in one's codes.