In the function evolve_step(), we encounter the first case where specific memory allocation and deallocation occurs more often than once during a run:
As we have seen already in chapter 6, the Hermite code requires
knowledge of the values of all four dynamical variables at the
previous time step, indicated here by the prefix old_. Since
we do not want to introduce global variables, and since these
variables are not needed outside the context of the current function,
we allocate the memory in the first four lines, and free up those
memory locations in the last four lines. If we now would omit those
last four lines, the resulting memory leak could let us run into
serious trouble. For example, taking a million time steps with a
hundred-body system would cause us to loose words or
bytes for each particle for each time step, leading to a
total memory loss of
bytes or roughly ten Gbytes, which
may well be larger than the core memory of the computer at hand.
Again, it would be very good if we checked with each call to new whether there is still enough memory available. Since we do not do that here, a memory leak will suddenly cause the program to crash, without giving us any clue of where to look. Even using a debugger may not help, since the actual crash may well occur somewhere else, where a small amount of legitimate memory is requested, only to find out that all memory has just been exhausted elsewhere in the code. Once more, we will postpone but not neglect this type of defensive programming.
After the current values of the dynamical variables have been passed to the old_ copies, we take the first half of a Hermite pass, in a call to predict_step(), followed by a recalculation of accelerations and jerks, as well as potential energy and collision time scale. We are then ready to complete the Hermite step through a call to correct_step(), and update the time t.