Memory Handling Notes

Memory Strategy
The underlying rule of the c++ pipeline is that the creator of the memory is responsible for managing it and cleaning it up. The motto is "You create it, you delete it". Pieces of code that wish to persist dynamic data must make a copy. In particular, the data framework makes a copy of all data that is passed to it -- it stores copies of the arrays that are passed! This means that modules must delete their arrays (assuming, of course, that they created the memory in the first place).

However, note that getting arrays from the data stream is not considered a memory allocation. So these arrays should not be deleted by the code! This is a direct pointer into the data stream memory, so any modification directly affect the data stream arrays. There is not need to call the set method again.

This strategy is intended to keep the memory allocation rules as simple as possible. In each class, each new should be matched with a corresponding delete.

Example
In PlaceObjects.cc, the process() block creates a new array to contain the x-coordinates of the galaxies. The code goes:

double *ox = new double[num];
...
event["image"].set("ObjectX",ox,num);
...
delete[] ox;

Here the module uses new to allocate memory. This makes it responsible for cleaning up this memory, which it does with a delete at the end of the function. It needs to delete the memory even though it was set in the event -- the event makes a copy during the set!

Exceptions
Occasionally an exception in the memory ownership rules are necessitated for performance reasons. In these cases, a special set function allows a module to bypass the array copy, and simply hand the data stream memory to store without making any further allocation. This is a transfer of the ownership of the memory -- the data stream inherits ownership and the code that created the memory should not delete it. Grep the code for setNoRealloc for examples.

Making an exception to the memory allocation rules is not generally advised, as it complicated the entire memory handling strategy. The normal set and get routines should suffice for almost all tasks without hindering performance.