AFF --- A container for numbers (array) by Friederich and Forbriger.
The concept of represented memory

Contents of this page:

Introduction

The array and iterator classes in this library should be insulated from the representation of the handled data in memory. Also they should be able to share references to the same memory area. Since returning an array from a function automatically invokes the copy constructor, this representation should have reference semantics. Using the same representation class (here aff::SharedHeap) as a basis for all containers (like aff::Array and aff::Series) and iterators, we may easily convert an aff::Series into an aff::Array without copying the data. Both objects just provide a different access interface to the data in memory.

To use memory representations with reference semantics has some implications for the definition of the assignment operator. We have to decide between a deep copy (elementwise copy) and a shallow copy (copying the representation).

See also
Copy constructor and copy operator

Shared heap

This type of memory access implements array handle semantics. On creation this class allocates memory on the free store (heap) to be used for the array elements. On a copy only a reference to the free store location is copied. Thus always a shallow copy is performed. The represenation itself takes care about the number of instances referencing the free store location. On destruction of the last of these instances, the free store location is freed.

Additionally aff::SharedHeap offers a facility to take a global memory pointer on creation. In this case, memory management lies outside the representation class and the underlying aff::SHeap object will never call the delete operator in the destructor. This is usefull when interfacing arrays allocated through Fortran code subroutines.

Creating an array projection may be done by copying the representation (reference to free store) with an array instance that only accesses a subset of the elements in the heap location. Thus projections may be created as true arrays (you don't have do distinguish between projections and true arrays in your code - like the sliced arrays in the STL must). However, changes applied to the array elements through the projection imediately affects the full array, in fact data of all array copies are affected by "write"-operations to the instances.

This way of memory access allows easy and cheap copying of arrays. We may pass them freely to functions or receive them as return values. It doesn't matter where the array is actually created. Itself takes care about memory allocation. And it always does a shallow copy, with almost no overhead to passing a reference.

By this mechanism, we may hold different projections to the same data, which are all full qualified arrays (even with possibly different dimensionality). For example, we may hold a complete set of earth model parameters. We may like to address them either in the sense of inversion parameters as a full set or in the sense of there physical meaning. In the latter case we may like to address the p-velocities as a subset. However, when any of the (anonymous) inversion parameters are changed, the change should immediatly be reflected by the projection that represents the physical parameters and vice versa.

The same memory data may even be shared by objects of different class types. In this way an aff::Array may interface the same data in memory as a simultaneous aff::Series object.

This is implemented by class aff::SharedHeap. It is presented in aff/lib/sharedheap.h

See also
Notes on the const-correctness of arrays