BDE 4.14.0 Production release
|
Macros | |
#define | bslma_AutoDeallocator bslma::AutoDeallocator |
This alias is defined for backward compatibility. | |
Provide a range proctor to managed a block of memory.
This component provides a range proctor class template, bslma::AutoDeallocator
, to manage a sequence of blocks of (otherwise-unmanaged) memory of parameterized TYPE
supplied at construction. If not explicitly released, the sequence of managed memory blocks are deallocated automatically when the range proctor goes out of scope by freeing the memory using the parameterized ALLOCATOR
(allocator or pool) supplied at construction. Note that after a range proctor releases its managed sequence of memory, the same proctor can be reused to conditionally manage another sequence of memory (allocated from the same allocator or pool that was supplied at construction) by invoking the reset
method.
The parameterized ALLOCATOR
type of the bslma::AutoRawDeleter
class template must provide a (possibly virtual
) method:
to deallocate memory at the specified address
(originally supplied by the ALLOCATOR
object).
The bslma::AutoDeallocator
proctor object can be used to achieve exception safety in an exception neutral way during manipulation of "out-of-place" arrays of raw resources or memory. Since there are no destructor calls, this component is more efficient compared to the bslma::AutoRawDeleter
. The following illustrates the insertion operation for an "out-of-place" array of raw character sequences. Assume that an array initially contains 5 character sequences as its elements:
To insert two more character sequences at index position 2, the array is first reallocated if it is not big enough, and then the existing elements at index positions 2, 3, and 4 are shifted:
Next, two new memory blocks must be allocated to position 2 and 3. If, one of the two allocations fails and an exception is thrown, the array will be left in an invalid state because the addresses contained at index positions 2 and 3 may be duplicates of those at index positions 4 and 5, or, if a resize occurred, invalid altogether. We can restore exception neutrality by setting the array's length to 2 before attempting to create the string objects, but there is still a problem: the character sequences "Bloom", "berg", and "LP" (at index positions 4, 5, and 6) are "orphaned" and will never be deallocated – a memory leak. To prevent this potential memory leak, we can additionally create a bslma::AutoDeallocator
object to manage (temporarily) the memory at index positions 4, 5, and 6 prior to allocating the new memory:
If an exception occurs, the array (now of length 2) is in a perfectly valid state, while the proctor is responsible for deallocating the orphaned memory at index positions 4, 5, and 6. If no exception is thrown, the length is set to 7 and the proctor's release
method is called, releasing its control over the (temporarily) managed memory.
The following example illustrates the use of bslma::AutoDeallocator
to manage temporarily an "out-of-place" array of character sequences during the array's insertion operation.
First we define a my_StrArray
class that stores an array of character sequences.
Next, we define the insert
method of my_StrArray
:
Now, if any allocation for the inserted character sequences throws, the memory used for the character sequences that had been moved to the end of array will be deallocated automatically by the bslma::AutoDeallocator
.
The above method copies the source elements (visually) from left to right. Another (functionally equivalent) implementation copies the source elements from right to left, and makes use of the operator--()
of the bslma::AutoDeallocator
interface:
Since we have decided to copy the source elements from right to left, we set the origin of the bslma::AutoDeallocator
to the end of the array, and decrement the (signed) length on each copy to extend the proctor range by 1.
Note that though the two implementations are functionally equivalent, they are logically different. First of all, the second implementation will be slightly slower because it is accessing memory backwards when compared to the normal forward sequential access. Secondly, in case of an exception, the first implementation will retain all the elements copied prior to the exception, whereas the second implementation will remove them.
#define bslma_AutoDeallocator bslma::AutoDeallocator |