Re: reclaiming memory guarantees
iy@mailinator.com ha scritto:
"... The primary design criterion for the default STL allocator was
to make it no slower than the HP STL per-class allocators, but potentially
thread-safe, and significantly less prone to fragmentation. Like the HP
allocators, it does not maintain the necessary data structures to free
entire chunks of small objects when none of the contained small objects
are in use. This is an intentional choice of execution time over space
use. It may not be
appropriate for all programs. On many systems malloc_alloc may be more
space efficient, and can be used when that is crucial."
It doesn't look possible to deduce from the quote above what really
happens with the swap trick, when the standard allocator (and not
malloc_alloc) is used. Of course, it doesn't discuss the distinction
between swap and erase. And it shouldn't. It only says the memory may
not be released anyway - but wouldn't the same apply to any erase, both
vectors and maps, say, possibly rendering the swap trick useless in _all
cases_ ?
You are making a big confusion, IMHO. There are (at least) three levels
of memory "usage" to consider:
1) memory under OS control: this memory is available for any use. It may
or may not be costly to get, especially in little chunks.
2) memory under allocator control: this memory is available for any use
but only through the allocator itself. When the allocator runs out of
memory, it reclaims some more from the OS. When the allocator has unused
memory, it may release it to the OS or keep it. (A degenerate allocator
will always release it, such an allocator will never keep memory under
its control)
3) memory under container control: this memory is available to the
container only.
But now the big question is: what is "free" memory? Can you say that
memory of type 2 is not "free"? It is indeed available for any other
container using the same allocator. If all your containers use the same
allocator, what difference does it make if the memory comes directly
from the OS or from the allocator itself? If you are using the default
allocator, which relies on ::operator new and ::operator delete, then
the memory is also available for all other "normal" allocation through
non-overridden new/delete.
The big issue about the swap() trick is that containers (in particular
std::vector) are allowed to keep some memory of type 3 even if they are
not using it. Such memory can be thought as been wasted, because the
container is not using it and no other container has access to it. Yet
the container can think of it as "free" memory!
By using the swap trick, you have the guarantee (trust me) that all
memory of type 3 is returned to the allocator. Now, the allocator has a
choice: either keep it (the memory becomes of type 2) or release it to
the OS (the memory becomes of type 1). In either case, the memory can be
considered "free" from a certain point of view.
You have to look at the big picture. There is no absolute "free" or
"allocated" memory. It's all about who has control on the memory and how
such control is transfered. Whenever you speak about "free" memory, be
sure to have a clear point of view of what you mean by that.
HTH,
Ganesh
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]