// bslma_mallocfreeallocator.h -*-C++-*- #ifndef INCLUDED_BSLMA_MALLOCFREEALLOCATOR #define INCLUDED_BSLMA_MALLOCFREEALLOCATOR #include <bsls_ident.h> BSLS_IDENT("$Id: $") //@PURPOSE: Provide malloc/free adaptor to 'bslma::Allocator' protocol. // //@CLASSES: // bslma::MallocFreeAllocator: support malloc/free style allocate/deallocate // //@SEE_ALSO: bslma_newdeleteallocator, bslma_allocator // //@DESCRIPTION: This component provides an allocator, // 'bslma::MallocFreeAllocator', that implements the 'bslma::Allocator' // protocol and supplies memory using the system-supplied (native) // 'std::malloc' and 'std::free' operators. //.. // ,--------------------------. // ( bslma::MallocFreeAllocator ) // `--------------------------' // | ctor/dtor // | singleton // V // ,----------------. // ( bslma::Allocator ) // `----------------' // allocate // deallocate //.. // The key purpose of this component is to facilitate the use of 'malloc' and // 'free' when the default 'bslma::NewDeleteAllocator' is not desirable (such // as the case of 'bslma::TestAllocator'). To accomplish this goal, 'malloc' // and 'free' are wrapped in a singleton object whose lifetime is guaranteed to // exceed any possibility of its use. // ///Thread Safety ///------------- // A single object of 'bslma::MallocFreeAllocator' is safe for concurrent // access by multiple threads. The underlying implementation of 'malloc' and // 'free' will ensure that heap corruption does not occur. Note that this // allocator therefore has a stronger thread safety guarantee than is required // by the base-class contract or than is provided by other allocators. // ///Usage ///----- // This component is intended to be used when the use of 'new' and 'delete' are // not desirable, such as the case of 'bslma::TestAllocator'. Instead of using // 'bslma::Default' which uses the 'bslma::NewDeleteAllocator', this component // can be used to bypass the use of 'new' and 'delete'. // // The following example demonstrates the use of this component for a user // defined allocator instead of using the default allocator: //.. // // my_allocator.h // // ... // // class my_Allocator : public bslma::Allocator { // // This class provides a mechanism for allocation and deallocation. // // // DATA // bslma::Allocator *d_allocator_p; // allocator (held, not owned) // // public: // // CREATORS // my_Allocator(bslma::Allocator *basicAllocator = 0); // // Create a 'my_Allcoator'. Optionally specify 'basicAllocator' to // // supply memory. If 'basicAllocator' is 0, the // // 'bslma::MallocFreeAllocator' will be used. // // ~my_Allocator(); // // Destroy this allocator. Note that the behavior of destroying an // // allocator while memory is allocated from it is not specified. // // (Unless you *know* that it is valid to do so, don't!) // // // MANIPULATORS // void *allocate(size_type size); // // Return a newly allocated block of memory of (at least) the // // specified positive 'size' (bytes). If 'size' is 0, a null // // pointer is returned with no effect. Note that the alignment of // // the address returned is the maximum alignment for any // // fundamental type defined for this platform. // // void deallocate(void *address); // // Return the memory at the specified 'address' back to this // // allocator. If 'address' is 0, this function has no effect. The // // behavior is undefined if 'address' was not allocated using this // // allocator, or has already been deallocated. // }; //.. // The constructor is implemented using 'bslma::MallocFreeAllocator'. //.. // // my_allocator.cpp // // ... // // // CREATORS // my_Allocator::my_Allocator(bslma::Allocator *basicAllocator) // : d_allocator_p(basicAllocator // ? basicAllocator // : &bslma::MallocFreeAllocator::singleton()) // { // } // // // ... //.. // When the 'basicAllocator' is not specified, the 'bslma::MallocFreeAllocator' // will be used. That allocator then then calls 'std::malloc' and 'std::free' // for allocating and deallocating memory. #include <bslscm_version.h> #include <bslma_allocator.h> #include <cstdlib> // 'std::malloc', 'std::free' namespace BloombergLP { namespace bslma { // ========================= // class MallocFreeAllocator // ========================= class MallocFreeAllocator : public Allocator { // This class provides direct access to the system-supplied (native) global // 'std::malloc' and 'std::free'. A 'static' method is provided for // obtaining a unique, process wide object of this class, which is valid // from the time the method is called until after the program (not just // 'main') exits. private: // NOT IMPLEMENTED MallocFreeAllocator(const MallocFreeAllocator&); MallocFreeAllocator& operator=(const MallocFreeAllocator&); public: // CLASS METHODS static MallocFreeAllocator& singleton(); // Return a reference to a valid object of this class. Note that this // object is guaranteed to be valid from the time of this call onward // (i.e., not just until exiting 'main'). // CREATORS MallocFreeAllocator(); // Create an allocator that uses 'std::malloc' and 'std::free' to // supply memory. Note that all objects of this class share the same // underlying resource. virtual ~MallocFreeAllocator(); // Destroy this allocator. Note that the behavior of destroying an // allocator while memory is allocated from it is not specified. // (Unless you *know* that it is valid to do so, don't!) // // For this concrete implementation, destroying this allocator object // has no effect on allocated memory. // MANIPULATORS virtual void *allocate(size_type size); // Return a newly allocated block of memory of (at least) the specified // positive 'size' (in bytes). If 'size' is 0, a null pointer is // returned with no other effect. If this allocator cannot return the // requested number of bytes, then it will return a null pointer. The // behavior is undefined unless '0 <= size'. Note that the alignment // of the address returned is the maximum alignment for any type // defined on this platform. Also note that 'std::malloc' is *not* // called when 'size' is 0 (in order to avoid having to acquire a lock, // and potential contention in multi-treaded programs). virtual void deallocate(void *address); // Return the memory block at the specified 'address' back to this // allocator. If 'address' is 0, this function has no effect. The // behavior is undefined unless 'address' was allocated using this // allocator object and has not already been deallocated. Note that // 'std::free' is *not* called when 'address' is 0 (in order to avoid // having to acquire a lock, and potential contention in multi-treaded // programs). }; // ============================================================================ // INLINE DEFINITIONS // ============================================================================ // ------------------------- // class MallocFreeAllocator // ------------------------- // CREATORS inline MallocFreeAllocator::MallocFreeAllocator() { } inline MallocFreeAllocator::~MallocFreeAllocator() { } // MANIPULATORS inline void MallocFreeAllocator::deallocate(void *address) { // While the C and C++ standard guarantees that calling free(0) is safe // (3.7.3.2 paragraph 3), some libc implementations take out a lock to deal // with the free(0) case, so this check can improve efficiency of threaded // programs. if (address) { std::free(address); } } } // close package namespace #ifndef BDE_OPENSOURCE_PUBLICATION // BACKWARD_COMPATIBILITY // ============================================================================ // BACKWARD COMPATIBILITY // ============================================================================ typedef bslma::MallocFreeAllocator bslma_MallocFreeAllocator; // This alias is defined for backward compatibility. #endif // BDE_OPENSOURCE_PUBLICATION -- BACKWARD_COMPATIBILITY } // close enterprise namespace #endif // ---------------------------------------------------------------------------- // Copyright 2013 Bloomberg Finance L.P. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // ----------------------------- END-OF-FILE ----------------------------------