BDE 4.14.0 Production release
|
Provide an allocator-wrapper to allocate with a minimum alignment.
This component defines a concrete allocator implementation, bdlma::AligningAllocator
, providing the ability to allocate memory with a minimum alignment specified at the construction of the allocator. The following inheritance diagram shows the classes involved and their methods:
The AligningAllocator
is supplied an allocator at construction, and ensures that memory returned by allocate
meets a minimum alignment requirement. This may be useful in situations where a user needs to adapt an allocator supplying only natural alignment to software expecting an allocator with a higher alignment guarantee. The allocator supplied to an AligningAllocator
at construction is held, not owned.
The allocator supplied to the aligning allocator must employ at least the natural alignment strategy (see bsls_alignment ). Specifically, the aligning allocator will fail to properly align memory if the allocator passed to it employs the 1-byte alignment strategy.
Note that in order to provide the requested alignment an AligningAllocator
will need to always overallocate memory from the underlying allocator. This can "waste" space equal to the alignment plus some extra bytes for bookkeeping information. For small allocations with large alignment values this waste can be very impactful. In general, this means this component should be used with small alignments or with larger allocations.
This section illustrates intended use of this component.
Suppose we are dealing with an externally supplied library function that creates a linked list of null-terminated strings, and we want to use a default-constructed buffered sequential allocator for memory allocation.
First, the externally supplied library defines the struct
describing a node in the linked list:
Then, the externally-supplied library defines the function that will create the linked list of nodes from a null-terminated array of pointers to C-strings:
Next, our example function will begin with the externally-supplied buffered sequential allocator that we are to use:
There is a problem here, in that the nodes must be aligned by sizeof(Node *)
, but our buffered sequential allocator, like most BDE allocators, has a "natural alignment" strategy (see bsls_alignment ), meaning that it infers the required alignment from the size of the allocation requested. This would normally give us properly aligned memory if we were allocating by sizeof(Node)
, but our Node
objects are variable length, which will mislead the allocator to sometimes align the new segments by less than sizeof(Node *)
.
Then, we solve this problem by using an aligning allocator to wrap the buffered sequential allocator, ensuring that the memory will still come from the buffered sequential allocator, but nonetheless be aligned to the alignment requirement of Node
.
Next, we define a null-terminated array of strings we would like to store in the list:
Now, we call the function to put the strings into a linked list, passing it the aligning allocator:
Finally, we traverse the list and print out the strings, verifying that the nodes are properly aligned: