BDE 4.14.0 Production release
|
Macros | |
#define | BSLMA_TESTALLOCATOR_EXCEPTION_TEST_BEGIN(BSLMA_TESTALLOCATOR) |
#define | BSLMA_TESTALLOCATOR_EXCEPTION_TEST_END |
#define | BEGIN_BSLMA_EXCEPTION_TEST BSLMA_TESTALLOCATOR_EXCEPTION_TEST_BEGIN(testAllocator) |
#define | END_BSLMA_EXCEPTION_TEST BSLMA_TESTALLOCATOR_EXCEPTION_TEST_END |
Typedefs | |
typedef bslma::TestAllocator | bslma_TestAllocator |
This alias is defined for backward compatibility. | |
Provide instrumented malloc/free allocator to track memory usage.
malloc
/free
memory allocatorThis component provides an instrumented allocator, bslma::TestAllocator
, that implements the bslma::Allocator
protocol and can be used to track various aspects of memory allocated from it. Available statistics include the number of outstanding blocks (and bytes) that are currently in use, the cumulative number of blocks (and bytes) that have been allocated, and the maximum number of blocks (and bytes) that have been in use at any one time. A print
function formats these values to stdout
:
If exceptions are enabled, this allocator can be configured to throw an exception after the number of allocation requests exceeds some specified limit (see the subsection on "Allocation Limit" below). The level of verbosity can also be adjusted. Each allocator object also maintains a current status.
By default this allocator gets its memory from the C Standard Library functions malloc
and free
, but can be overridden to take memory from any allocator (supplied at construction) that implements the bslma::Allocator
protocol. Note that allocation and deallocation using a bslma::TestAllocator
object is explicitly incompatible with malloc
and free
(or any other allocation mechanism). Attempting to use free
to deallocate memory allocated from a bslma::TestAllocator
– even when malloc
and free
are used by default – will result in undefined behavior, almost certainly corrupting the C Standard Library's runtime memory manager.
Memory dispensed from a bslma::TestAllocator
is marked such that attempting to deallocate previously unallocated (or already deallocated) memory will (with high probability) be flagged as an error (unless quiet mode is set for the purpose of testing the test allocator itself). A bslma::TestAllocator
also supports a buffer overrun / underrun feature – each allocation has "pads", areas of extra memory before and after the segment that are initialized to a particular value and checked upon deallocation to see if they have been modified. If they have, a message is printed and the allocator aborts, unless it is in quiet mode.
The bslma::TestAllocator
is useful for detecting memory leaks, unless configured in quiet mode. With the default configuration, if a test allocator is destroyed before all memory is reclaimed, a report will be logged and abort
will be called. When such a memory leak is detected, clients can substitute balst::StackTraceTestAllocator
for bslma::TestAllocator
to report stack traces of allocations that were leaked. Note that balst::StackTraceTestAllocator
is slower and consumes more memory than bslma::TestAllocator
, and usually is not appropriate for automated tests.
The test allocator's behavior is controlled by three basic mode flags:
VERBOSE MODE: (Default 0) Specifies that each allocation and deallocation should be printed to standard output. In verbose mode all state variables will be displayed at destruction.
QUIET MODE: (Default 0) Specifies that mismatched memory and memory leaks should not be reported, and should not cause the process to terminate when detected. Note that this mode is used primarily for testing the test allocator itself; behavior that would otherwise abort now quietly increments the numMismatches
and numBoundsErrors
counter.
NO-ABORT MODE: (Default 0) Specifies that the test allocator should not invoke abort
under any circumstances without suppressing diagnostics. Although the internal state values are independent, quiet mode implies the behavior of no-abort mode in all cases. Note that this mode is used primarily for visual inspection of unusual error diagnostics in this component's test driver (in non-quiet mode only).
Taking the default mode settings, memory allocation/deallocation will not be displayed individually. However, in the event of a mismatched deallocation or a memory leak detected at destruction, the problem will be announced, any relevant state of the object will be displayed, and the program will abort.
The three modes are independently set using the setVerbose
, setQuiet
, and setNoAbort
manipulators.
If exceptions are enabled at compile time, the test allocator can be configured to throw a bslma::TestAllocatorException
after a specified number of allocation requests is exceeded. If the allocation limit is less than 0 (default), then the allocator won't throw a TestAllocatorException
exception. Note that a non-negative allocation limit is decremented after each allocation attempt, and an exception is thrown only when the current allocation limit transitions from 0 to -1; no additional exceptions will be thrown until the allocation limit is again reset to a non-negative value.
The allocation limit is set using the setAllocationLimit
manipulator.
This component also provides a pair of macros:
BSLMA_TESTALLOCATOR_EXCEPTION_TEST_BEGIN(BSLMA_TESTALLOCATOR)
BSLMA_TESTALLOCATOR_EXCEPTION_TEST_END
These macros can be used for testing exception-safety of classes and their methods when memory allocation is needed. A reference to an object of type bslma::TestAllocator
must be supplied as an argument to the _BEGIN
macro. Note that if exception-handling is disabled (i.e., if BDE_BUILD_TARGET_EXC
is not defined when building the code under test), then the macros simply print the following:
When exception-handling is enabled, the _BEGIN
macro will set the allocation limit of the supplied allocator to 0, try
the code being tested, catch
any TestAllocatorException
s that are thrown, and keep increasing the allocation limit until the code being tested completes successfully.
The bslma::TestAllocator
class is fully thread-safe (see bsldoc_glossary ). Note that the bslma::MallocFreeAllocator
singleton (the allocator used by the test allocator if none is supplied at construction) is fully thread-safe.
The bslma::TestAllocator
defined in this component can be used in conjunction with the BSLMA_TESTALLOCATOR_EXCEPTION_TEST_BEGIN
and BSLMA_TESTALLOCATOR_EXCEPTION_TEST_END
macros to test the memory usage patterns of an object that uses the bslma::Allocator
protocol in its interface. In this example, we illustrate how we might test that an object under test is exception-neutral. For illustration purposes, we will assume the existence of a my_shortarray
component implementing an std::vector
-like array type, myShortArray
:
Below we provide a static
function, areEqual
, that will allow us to compare two short arrays:
The following is an abbreviated standard test driver. Note that the number of arguments specify the verbosity level that the test driver uses for printing messages:
We now define a bslma::TestAllocator
, sa
, named "supplied" to indicate that it is the allocator to be supplied to our object under test, as well as to the BSLMA_TESTALLOCATOR_EXCEPTION_TEST_BEGIN
macro (below). Note that if veryVeryVeryVerbose
is true
, then sa
prints all allocation and deallocation requests to stdout
and also prints the accumulated statistics on destruction:
All code that we want to test for exception-safety must be enclosed within the BSLMA_TESTALLOCATOR_EXCEPTION_TEST_BEGIN
and BSLMA_TESTALLOCATOR_EXCEPTION_TEST_END
macros, which internally implement a do
-while
loop. Code provided by the BSLMA_TESTALLOCATOR_EXCEPTION_TEST_BEGIN
macro sets the allocation limit of the supplied allocator to 0 causing it to throw an exception on the first allocation. This exception is caught by code provided by the BSLMA_TESTALLOCATOR_EXCEPTION_TEST_END
macro, which increments the allocation limit by 1 and re-runs the same code again. Using this scheme we can check that our code does not leak memory for any memory allocation request. Note that the curly braces surrounding these macros, although visually appealing, are not technically required:
After the exception-safety test we can ensure that all the memory allocated from sa
was successfully deallocated:
Note that the BDE_BUILD_TARGET_EXC
macro is defined at compile-time to indicate whether or not exceptions are enabled.
#define BEGIN_BSLMA_EXCEPTION_TEST BSLMA_TESTALLOCATOR_EXCEPTION_TEST_BEGIN(testAllocator) |
#define BSLMA_TESTALLOCATOR_EXCEPTION_TEST_BEGIN | ( | BSLMA_TESTALLOCATOR | ) |
#define BSLMA_TESTALLOCATOR_EXCEPTION_TEST_END |
#define END_BSLMA_EXCEPTION_TEST BSLMA_TESTALLOCATOR_EXCEPTION_TEST_END |