BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bslma_defaultallocatorguard

Typedefs

typedef bslma::DefaultAllocatorGuard bslma_DefaultAllocatorGuard
 This alias is defined for backward compatibility.
 

Detailed Description

Outline

Purpose

Provide scoped guard to temporarily change the default allocator.

Classes

See also
bslma_allocator, bslma_default

Description

This component provides an object, bslma::DefaultAllocatorGuard, that serves as a "scoped guard" to enable the temporary replacement of the process-wide default allocator. This functionality is intended for testing only, and in no event should this component be used except in main.

The guard object takes as its constructor argument the address of an object of a class derived from bslma::Allocator. The default allocator at the time of guard construction is held by the guard, and the constructor-argument allocator is installed as the new process-wide default allocator (via a call to bslma::Default::setDefaultAllocatorRaw). Upon destruction of the guard object, its held allocator is restored as the process-wide default allocator (via another call to bslma::Default::setDefaultAllocatorRaw).

Usage

The bslma_default component ensures that, unless the owner of main or some intervening code explicitly installs a default allocator, the bslma::NewDeleteAllocator::singleton() will be the default allocator for that process (i.e., calls to bslma::Default::defaultAllocator() will return the new-delete allocator unless someone has set the default allocator to a different allocator intentionally). Consider for purposes of this illustrative example the case where we, as owners of a test driver main, can count on the bslma::NewDeleteAllocator singleton being the default.

Consider now that, for testing purposes, we want a simple counting allocator that uses new and delete, and that also keeps count of the number of memory blocks that have been allocated but never deallocated. (Note that, in testing real production code, bslma::TestAllocator serves this purpose.)

class my_CountingAllocator : public bslma::Allocator
{
int d_blocksOutstanding;
public:
my_CountingAllocator();
~my_CountingAllocator();
virtual void *allocate(int size);
virtual void deallocate(void *address);
int blocksOutstanding() const { return d_blocksOutstanding; }
};
inline
my_CountingAllocator::my_CountingAllocator()
: d_blocksOutstanding(0)
{
}
inline
my_CountingAllocator::~my_CountingAllocator()
{
if (0 < d_blocksOutstanding) {
std::cout << "***ERROR: Memory Leak***" << std::endl
<< d_blocksOutstanding << " block(s) leaked. "
<< "Program aborting." << std::endl;
assert(0);
}
}
inline
void *my_CountingAllocator::allocate(int size)
{
++d_blocksOutstanding;
return operator new(size);
}
inline
void my_CountingAllocator::deallocate(void *address)
{
--d_blocksOutstanding;
operator delete(address);
}
Definition bslma_allocator.h:457
virtual void deallocate(void *address)=0
virtual void * allocate(size_type size)=0
bsl::size_t size(const TYPE &array)
Return the number of elements in the specified array.

We may now write a test driver for some component that uses a bslma::Allocator and the bslma::Default mechanism. First, we confirm that the bslma::NewDeleteAllocator singleton is indeed installed.

//my_component.t.cpp
// ...
int main()
{
// ...
Definition bslma_newdeleteallocator.h:301
static NewDeleteAllocator & singleton()
static Allocator * defaultAllocator()
Definition bslma_default.h:889

Now, we can go into some inner scope and use a guard object to install a test allocator as the default for any newly created objects. When the inner scope ends, the guard will be destroyed, automatically restoring the original default allocator.

{
my_CountingAllocator testAllocator;
bslma::DefaultAllocatorGuard guard(&testAllocator);
assert(&testAllocator == bslma::Default::defaultAllocator());
// Create and test the object under test, which will use the
// test allocator *by* *default*.
// ...
}
Definition bslma_defaultallocatorguard.h:186

If the test block above has a memory leak, the program will print an error to stdout and abort. Otherwise, the new-delete allocator will be re-installed as the default allocator, and the program will proceed to the next block of code.

Typedef Documentation

◆ bslma_DefaultAllocatorGuard