Reputation: 727
If I integrate a system with boosts odeint
module, using a class to define the derivative, the destructor of this class is called very often.
For example, this code:
#include <iostream>
#include <boost/numeric/odeint.hpp>
using namespace std;
using namespace boost::numeric::odeint;
class foo
{
public:
virtual ~foo() {
std::cout << "destructor called" << std::endl;
}
void operator()(const double &x, double &dxdt, double t) const {
dxdt = 1;
}
};
int main( int argc , char **argv )
{
double x = 0;
const double dt = 0.1;
typedef runge_kutta4< double > stepper_type;
integrate_const( stepper_type() , foo(), x , 0.0 , 10.0 , dt);
return 0;
}
calls the destructor around 400 times. (I'am a beginner in c++)
Upvotes: 3
Views: 136
Reputation: 23818
The destructor is only called once at the end of the program if
foo
in main and std::ref()
is used in the call to integrate_const()
Like this:
#include <iostream>
#include <boost/numeric/odeint.hpp>
#include <functional>
using namespace boost::numeric::odeint;
class foo
{
public:
virtual ~foo() {
std::cout << "destructor called" << std::endl;
}
void operator()(const double &x, double &dxdt, double t) const {
dxdt = 1;
}
};
int main( int argc , char **argv )
{
double x = 0;
const double dt = 0.1;
typedef runge_kutta4< double > stepper_type;
foo myfoo;
integrate_const( stepper_type() , std::ref( myfoo ), x , 0.0 , 10.0 , dt);
return 0;
}
You can allocate any kind of data dynamically in the foo class, for instance by adding a simple setter function .setData()
that could be called from main
with
myfoo.setData(myArray);
prior to the call to integrate_const()
.
Upvotes: 1
Reputation: 35458
Simple: just trace back the calls in a debugger to your destructor.
You will see that the first level is:
template<class Stepper, class System, class State, class Time>
size_t integrate_const(
Stepper stepper, System system, State &start_state,
Time start_time, Time end_time, Time dt)
which after several intermediary steps has a loop in it:
while( less_eq_with_sign( static_cast<Time>(time+dt) , end_time , dt ) )
{
obs( start_state , time );
st.do_step( system , start_state , time , dt );
...
found in usr/include/boost/numeric/odeint/integrate/detail/integrate_const.hpp:59
and unfortunately all the parameters are being sent down via value, not reference in the boost code. So it will create and destroy a lot of temporary objects based from the one you have created.
If you want to allocate arrays dynamically I would recommend to use std::vector
because approaching this issue via C style arrays will take a lot of time to debug.
Upvotes: 1