Software: Apache/2.0.54 (Fedora). PHP/5.0.4 uname -a: Linux mina-info.me 2.6.17-1.2142_FC4smp #1 SMP Tue Jul 11 22:57:02 EDT 2006 i686 uid=48(apache) gid=48(apache) groups=48(apache) Safe-mode: OFF (not secure) /usr/share/doc/libstdc++-devel-4.0.2/html/20_util/ drwxr-xr-x |
Viewing file: Select action/file-type: Allocators and allocationThe latest version of this document is always available at http://gcc.gnu.org/onlinedocs/libstdc++/20_util/allocator.html. To the libstdc++-v3 homepage. The C++ Standard encapsulates memory management characteristics
for strings, container classes, and parts of iostreams in a
template class called Standard requirementsThe C++ standard only gives a few directives in this area:
Complete details cam be found in the C++ standard, look in [20.4 Memory]. Problems and PossibilitiesThe easiest way of fulfilling the requirements is to call operator new each time a container needs memory, and to call operator delete each time the container releases memory. BUT this method is horribly slow. Or we can keep old memory around, and reuse it in a pool to save time. The old libstdc++-v2 used a memory pool, and so do we. As of 3.0, it's on by default. The pool is shared among all the containers in the program: when your program's std::vector<int> gets cut in half and frees a bunch of its storage, that memory can be reused by the private std::list<WonkyWidget> brought in from a KDE library that you linked against. And we don't have to call operators new and delete to pass the memory on, either, which is a speed bonus. BUT... What about threads? No problem: in a threadsafe environment, the memory pool is manipulated atomically, so you can grow a container in one thread and shrink it in another, etc. BUT what if threads in libstdc++-v3 aren't set up properly? That's been answered already. BUT what if you want to use your own allocator? What if you plan on using a runtime-loadable version of malloc() which uses shared telepathic anonymous mmap'd sections serializable over a network, so that memory requests should go through malloc? And what if you need to debug it?
Implementation details of
|
Allocator (3.4) | Header (3.4) | Allocator (3.[0-3]) | Header (3.[0-3]) |
---|---|---|---|
__gnu_cxx::new_allocator<T> | <ext/new_allocator.h> | std::__new_alloc | <memory> |
__gnu_cxx::malloc_allocator<T> | <ext/malloc_allocator.h> | std::__malloc_alloc_template<int> | <memory> |
__gnu_cxx::debug_allocator<T> | <ext/debug_allocator.h> | std::debug_alloc<T> | <memory> |
__gnu_cxx::__pool_alloc<T> | <ext/pool_allocator.h> | std::__default_alloc_template<bool,int> | <memory> |
__gnu_cxx::__mt_alloc<T> | <ext/mt_allocator.h> | ||
__gnu_cxx::bitmap_allocator<T> | <ext/bitmap_allocator.h> |
Releases after gcc-3.4 have continued to add to the collection of available allocators. All of these new allocators are standard-style. The following table includes details, along with the first released version of GCC that included the extension allocator.
Allocator | Include | Version |
---|---|---|
__gnu_cxx::array_allocator<T> | <ext/array_allocator.h> | 4.0.0 |
More details on each of these extension allocators follows.
new_allocator
Simply wraps ::operator new
and ::operator delete
.
malloc_allocator
Simply wraps
malloc
and free
. There is also a hook
for an out-of-memory handler (for new/delete this is taken care of
elsewhere).
array_allocator
Allows allocations of known and fixed sizes using existing
global or external storage allocated via construction of
std::tr1::array objects. By using this allocator, fixed size
containers (including std::string) can be used without
instances calling ::operator new
and
::operator delete
. This capability allows the
use of STL abstractions without runtime complications or
overhead, even in situations such as program startup. For
usage examples, please consult the libstdc++ testsuite.
debug_allocator
A wrapper around an
arbitrary allocator A. It passes on slightly increased size
requests to A, and uses the extra memory to store size information.
When a pointer is passed to deallocate()
, the stored
size is checked, and assert() is used to guarantee they match.
__pool_alloc
A high-performance, single pool allocator. The reusable
memory is shared among identical instantiations of this type.
It calls through ::operator new
to obtain new memory
when its lists run out. If a client container requests a block
larger than a certain threshold size, then the pool is bypassed,
and the allocate/deallocate request is passed to
::operator new
directly.
For versions of __pool_alloc
after 3.4.0, there is
only one template parameter, as per the standard.
Older versions of this class take a boolean template parameter,
called thr
, and an integer template parameter,
called inst
.
The inst
number is used to track additional memory
pools. The point of the number is to allow multiple
instantiations of the classes without changing the semantics at
all. All three of
typedef __pool_alloc<true,0> normal; typedef __pool_alloc<true,1> private; typedef __pool_alloc<true,42> also_private;
behave exactly the same way. However, the memory pool for each type (and remember that different instantiations result in different types) remains separate.
The library uses 0 in all its instantiations. If you wish to keep separate free lists for a particular purpose, use a different number.
The thr
boolean determines whether the pool should
be manipulated atomically or not. When thr=true, the allocator
is is threadsafe, while thr=false, and is slightly faster but
unsafe for multiple threads.
For thread-enabled configurations, the pool is locked with a single big lock. In some situations, this implementation detail may result in severe performance degredation.
(Note that the GCC thread abstraction layer allows us to provide safe zero-overhead stubs for the threading routines, if threads were disabled at configuration time.)
__mt_alloc
A high-performance fixed-size allocator. It has its own documentation, found here.
bitmap_allocator
A high-performance allocator that uses a bit-map to keep track of the used and unused memory locations. It has its own documentation, found here.
You can specify different memory management schemes on a
per-container basis, by overriding the default
Allocator
template parameter. For example, an easy
(but non-portable) method of specifying that only malloc/free
should be used instead of the default node allocator is:
std::list <int, __gnu_cxx::malloc_allocator<int> > malloc_list;Likewise, a debugging form of whichever allocator is currently in use:
std::deque <int, __gnu_cxx::debug_allocator<std::allocator<int> > > debug_deque;
Writing a portable C++ allocator would dictate that the
interface would look much like the one specified for
std::allocator
. Additional member functions, but not
subtractions, would be permissible.
Probably the best place to start would be to copy one of the
extension allocators already shipped with libstdc++: say,
new_allocator
.
ISO/IEC 14882:1998 Programming languages - C++ [20.4 Memory]
Austern, Matt, C/C++ Users Journal. The Standard Librarian: What Are Allocators Good For?
Berger, Emery, The Hoard memory allocator
Berger, Emery with Ben Zorn & Kathryn McKinley, OOPSLA 2002 Reconsidering Custom Memory Allocation
Kreft, Klaus and Angelika Langer, C++ Report, June 1998 Allocator Types
Stroustrup, Bjarne, 19.4 Allocators, The C++ Programming Language, Special Edition, Addison Wesley, Inc. 2000
Yen, Felix, Yalloc: A Recycling C++ Allocator
Return to the top of the page or to the libstdc++ homepage.
See license.html for copying conditions. Comments and suggestions are welcome, and may be sent to the libstdc++ mailing list.
:: Command execute :: | |
--[ c99shell v. 1.0 pre-release build #16 powered by Captain Crunch Security Team | http://ccteam.ru | Generation time: 0.0028 ]-- |