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

Macros

#define bslma_DeallocatorGuard   bslma::DeallocatorGuard
 This alias is defined for backward compatibility.
 

Detailed Description

Outline

Purpose

Provide a guard to unconditionally manage a block of memory.

Classes

See also
bslma_deallocatorproctor, bslma_autodeallocator

Description

This component provides a guard class template, bslma::DeallocatorGuard, to unconditionally manage a block of (otherwise-unmanaged) memory. The managed memory is deallocated automatically when the guard object goes out of scope using the deallocate method of the parameterized ALLOCATOR (allocator or pool) supplied at construction.

Requirement

The parameterized ALLOCATOR type of the bslma::DeallocatorGuard class template must provide a (possibly virtual) method:

void deallocate(void *address);

to deallocate memory at the specified address (originally supplied by the ALLOCATOR object).

Usage

A bslma::DeallocatorGuard can be used to ensure that a dynamically allocated raw memory resource is safely deallocated in the presence of multiple return statements or exceptions in an exception-neutral way (i.e., without the need for try/catch blocks). In this simple example, consider the function evaluatePassword which attempts to determine how secure a given password might be:

/// Evaluate the strength of the specified `password`, using the
/// specified `allocator` to supply memory for evaluation. Return a
/// real value in the range `[ 0.0 .. 1.0 ]` where 0.0 indicates the
/// weakest password, and 1.0 the strongest.
double evaluatePassword(const char *password, bslma::Allocator *allocator);
Definition bslma_allocator.h:457

This function will be implemented in terms of three exception neutral subroutines, each of which operates on a writable copy of the null-terminated password, (perturbing its contents slightly) and requiring unbounded amounts of scratch memory (to be allocated and deallocated from a supplied allocator):

int subroutine1(char *inOut, bslma::Allocator *allocator);
int subroutine2(char *inOut, bslma::Allocator *allocator);
int subroutine3(char *inOut, bslma::Allocator *allocator);

A final subroutine is then used to determine and return the score:

double finalSubroutine(const char *result);

The top-level routine is implemented as follows:

double evaluatePassword(const char *password, bslma::Allocator *allocator)
{
// Set up local writable copy of password in buffer.
size_t size = strlen(password) + 1;
char *buffer = (char *)allocator->allocate(size);
memcpy(buffer, password, size);
//**************************************************************
//* Note the use of the deallocator guard on 'buffer' (below). *
//**************************************************************
// Process and evaluate the supplied password.
if (0 != subroutine1(buffer, allocator)) {
return 0.0; // RETURN
}
if (0 != subroutine2(buffer, allocator)) {
return 0.2; // RETURN
}
if (0 != subroutine3(buffer, allocator)) {
return 0.4; // RETURN
}
return finalSubroutine(buffer);
} // note that 'buffer' is deallocated at end of block regardless
virtual void * allocate(size_type size)=0
Definition bslma_deallocatorguard.h:166

Notice that if any of the initial (numbered) subroutines returns a non-zero status value, the top-level evaluatePassword routine returns immediately with a predetermined score. Moreover, each of these routines may encounter a bad_alloc exception should the supplied allocator fail to return the requested memory. Even if all of these subroutines evaluates successfully, the score calculated using finalEval is returned directly by evaluatePassword, yet we still need to deallocate buffer. By guarding buffer with a bslma::DeallocatorGuard as shown above, all of these issues are fully addressed, and the top-level routine is also exception neutral as desired.

Macro Definition Documentation

◆ bslma_DeallocatorGuard

#define bslma_DeallocatorGuard   bslma::DeallocatorGuard