Topic: How to reduce a vector's capacity?
Author: Theodore Todorov <todorov@sbghp10.in2p3.fr>
Date: 1998/01/26 Raw View
Sorry for the (maybe) dumb question, but is there a way to
make a std::vector release (some of) the memory it has allocated
without deleting it entirely?
I couldn't find anything explicit in the CD2 public draft standard.
resize() is implemented thru erase() if the vector is shrinking
(23.2.4.2)
and erase() cannot relocate the elements before the first erased
element,
so it cannot free any storage unless it checks if the vector is
completely
erased, and the two implementations I looked at don't do that.
clear() would be a good way to free storage, but CD2 says it is
equivalent to erase(begin(),end()), so it cannot free storage either.
Even assignment of a shorter vector does not change the capacity
on the implementation I use (Rogue Wave STL bundled with HP aCC),
and CD2 seems to be silent on the subject.
Am I overlooking something or do I really have to use "new" and
"delete"
on a vector pointer if I need a long lived vector that does not grow
all the time?
I have tens of thousands of "long-lived" object instances in my
model,
each having a vector of some small thing, and the average size of the
vectors
is small (below 10) so memory usage is reasonable, but the fluctuations
from object to object are large, and some vector sizes can be 100 times
bigger. All these vectors are cleared before processing the next "event"
and if vector capacities are not reset most vectors will eventually
grow to large sizes, blowing up overall memory consumption.
Teddy Todorov (todorov@sbghp10.in2p3.fr)
[ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
[ about comp.lang.c++.moderated. First time posters: do this! ]
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: "Ross Smith" <ross.smith@nz.eds.com>
Date: 1998/01/27 Raw View
Theodore Todorov wrote ...
>
>Sorry for the (maybe) dumb question, but is there a way to
>make a std::vector release (some of) the memory it has allocated
>without deleting it entirely?
Just assign to it:
std::vector<foo> foo_vector;
// ...
// code that sticks a whole bunch of foos into foo_vector
// ...
foo_vector = std::vector<foo>();
// foo_vector is now reduced to minimum capacity
--
Ross Smith ............................. <mailto:ross.smith@nz.eds.com>
Internet and New Media, EDS (New Zealand) Ltd., Wellington, New Zealand
"The first thing we do, let's kill all the language lawyers."
-- Henry VI Part II, by W. Shakespeare;
additional dialogue by B. Stroustrup
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: "Paul D. DeRocco" <pderocco@ix.netcom.com>
Date: 1998/01/28 Raw View
Ross Smith wrote:
>
> Just assign to it:
>
> std::vector<foo> foo_vector;
> // ...
> // code that sticks a whole bunch of foos into foo_vector
> // ...
> foo_vector = std::vector<foo>();
> // foo_vector is now reduced to minimum capacity
That reduces its size, but doesn't necessary reduce its capacity (i.e., the
amount of memory allocated to it).
--
Ciao,
Paul
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: bparker@uq.net.au (Brian Parker)
Date: 1998/01/28 Raw View
On 27 Jan 1998 14:56:47 PST, "Ross Smith" <ross.smith@nz.eds.com>
wrote:
>Theodore Todorov wrote ...
>>
>>Sorry for the (maybe) dumb question, but is there a way to
>>make a std::vector release (some of) the memory it has allocated
>>without deleting it entirely?
>
>Just assign to it:
>
> std::vector<foo> foo_vector;
> // ...
> // code that sticks a whole bunch of foos into foo_vector
> // ...
> foo_vector = std::vector<foo>();
> // foo_vector is now reduced to minimum capacity
As mentioned in the original post, the CD2 gives no guarantees that
assignment will reduce the capacity of the assigned-to vector- in
fact, VC++ 5's STL does not. Moreover, if one uses the equivalent
assign() member function then it is guaranteed *not* to shrink the
assigned-to vector, and resize() similarly must not free memory.
(Interestingly, the technique of assigning another vector to return
memory is described in "The C++ Programming Language 3rd ed." 16.3.8,
so perhaps the intent, if not the wording, of the standard *is* to
free memory on assignment.)
I think that swapping with an empty vector will probably free all
memory in most implementations (under the CD2, swapping must be
constant time which, I think, pretty much guarantees that the usual
implementation of just swapping pointers to internal memory will be
used)- certainly, it works under VC++ 5.
i.e.
template<typename T>
void compact(std::vector<T>& v)
{
v.swap(std::vector<T>());
}
Personally, I think that some stronger post-conditions for these
memory-managment issues should have been specified in the standard.
Disclaimer: all of this is based on the CD2; the wording of the FDIS
may have changed.
,Brian Parker.
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: James Kuyper <kuyper@wizard.net>
Date: 1998/01/28 Raw View
Ross Smith wrote:
>
> Theodore Todorov wrote ...
> >
> >Sorry for the (maybe) dumb question, but is there a way to
> >make a std::vector release (some of) the memory it has allocated
> >without deleting it entirely?
>
> Just assign to it:
>
> std::vector<foo> foo_vector;
> // ...
> // code that sticks a whole bunch of foos into foo_vector
> // ...
> foo_vector = std::vector<foo>();
> // foo_vector is now reduced to minimum capacity
I may have misunderstood - doesn't that solution release ALL of the
memory, not just some of it? I thought that he wanted to keep some
portion of the foo_vector, while releasing the memory used to store the
rest.
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: msabin@cromwellmedia.co.uk (Miles Sabin)
Date: 1998/01/28 Raw View
On 26 Jan 1998 17:33:11 PST, Theodore Todorov
<todorov@sbghp10.in2p3.fr> wrote:
> Sorry for the (maybe) dumb question, but is there a way to
> make a std::vector release (some of) the memory it has allocated
> without deleting it entirely?
>
> I couldn't find anything explicit in the CD2 public draft standard.
> resize() is implemented thru erase() if the vector is shrinking
> (23.2.4.2) and erase() cannot relocate the elements before the
> first erased element, so it cannot free any storage unless it checks
> if the vector is completely erased, and the two implementations I
> looked at don't do that.
Your reading of CD2 is correct, but there is a workaround,
template<class T, class Allocator>
void trim(std::vector<T, Allocator>& v)
{
std::vector<T, Allocator> trimmed_v(v.begin(), v.end());
std::swap(v, trimmed_v);
}
Something similar will work for std::string and std::deque too.
Cheers,
Miles
[ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
[ about comp.lang.c++.moderated. First time posters: do this! ]
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: Valentin Bonnard <bonnardv@pratique.fr>
Date: 1998/01/29 Raw View
Theodore Todorov wrote:
>
> Sorry for the (maybe) dumb question, but is there a way to
> make a std::vector release (some of) the memory it has allocated
> without deleting it entirely?
The memory taken by a vector is O(capacity()). So using reserve
you should be able to manage that. At least it should... as
currently specified, it can hardly free storage as if its
argument is less than the current capacity, it doesn't change
anything. I think this is a bug in FDIS, as string::reserve
can shrink and expand. Added to my issues list.
--
Valentin Bonnard mailto:bonnardv@pratique.fr
info about C++/a propos du C++: http://www.pratique.fr/~bonnardv/
[ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
[ about comp.lang.c++.moderated. First time posters: do this! ]
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]