BDE 4.14.0 Production release
|
Provide pure procedures for allocating memory from a buffer.
This component provides a struct
, bdlma::BufferImpUtil
, that implements procedures for allocating memory from a buffer using an indicated memory alignment strategy. Each of the procedures take a buffer, the size of the buffer, a cursor pointing to the free memory within the buffer, and the allocation size. Two of the procedures, allocateFromBuffer
and allocateFromBufferRaw
, take an additional argument that specifies the memory alignment strategy to apply. The other six procedures apply a specific memory alignment strategy as indicated by their names (e.g., allocateNaturallyAlignedFromBuffer
and allocateMaximallyAlignedFromBufferRaw
). In all cases, a pointer to the allocated memory is returned, and the cursor passed in is updated to point to the portion of the buffer that contains the next available free memory.
For example, suppose we initially have a 2-byte aligned buffer having a size of 5 bytes, and a cursor pointing to the first byte:
Using natural alignment, suppose 1 byte is allocated from the buffer using allocateFromBuffer
:
The cursor will be advanced as follows:
Suppose allocateFromBuffer
is then used to allocate 2 bytes:
The cursor will be advanced as follows (after taking into consideration the alignment strategy used):
The byte at (only) position 1 is skipped because of the natural alignment strategy (otherwise, more bytes would have been skipped if maximum alignment was used). See bsls_alignment for more details about memory alignment.
The raw and non-raw versions differ in behavior only when the requested memory size is larger than the memory available within the provided buffer (after taking memory alignment into consideration). The raw versions result in undefined behavior, while the non-raw versions return 0. Note that the safety of the non-raw versions comes at the extra cost of a conditional statement. For example, clients of the non-raw versions must check the return value to ensure successful allocation.
This component is typically used by a class that manages a memory buffer. First, suppose we have a class that maintains a linked list of memory blocks, details of which are elided:
We can then create our memory manager using BlockList
:
The implementations of the constructor and destructor are elided since allocate
alone is sufficient to illustrate the use of bdlma::BufferImpUtil
:
Note that if there is insufficient space in d_buffer_p
, allocateFromBuffer
returns 0:
Note that the raw version is used because the contract of replenishBuffer
guarantees that the buffer will have sufficient space to satisfy the allocation request of the specified size
.