|
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_ENDThese 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 TestAllocatorExceptions 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 |