Use a ::std::vector
.
#include <vector>
void foo()
{
::std::vector<double> x;
x.resize(5);
x[4] = 2.0;
x.resize(2);
// etc...
}
The use cases you mention are exactly why ::std::vector
was made.
Now, if you resize a vector smaller, it does not normally deallocate memory. This is for a number of reasons, and this StackOverflow question on shrink_to_fit
describes why: Is shrink_to_fit the proper way of reducing the capacity a `std::vector` to its size?
But, if you really want to hint to the implementation that the extra points should be deallocated, do this:
#include <vector>
void foo()
{
::std::vector<double> x;
x.resize(5);
x.shrink_to_fit(); // It didn't get smaller here, but I'm guessing you may
x[4] = 2.0; // not know that when you resize the vector in your own code.
x.resize(2);
x.shrink_to_fit();
// etc...
}
The vector still may not actually shrink the allocation. That's an issue to take up with your implementation if it's really a problem.
If it is a problem, and you absolutely have to shrink the allocation and can't get the implementation to be fixed, then you could do this:
#include <iterator>
#include <algorithm>
#include <utility>
#include <vector>
template <class T>
void shrinkwrap_vector(::std::vector<T> &x)
{
using namespace ::std;
typedef vector<T> vec_t;
const auto old_cap = x.capacity();
x.shrink_to_fit(); // Try shrink_to_fit first to see if it works.
if ((x.capacity() == old_cap) && (old_cap > x.size())) {
vec_t t;
t.reserve(x.size());
move(x.begin(), x.end(), back_inserter(t));
swap(x, t);
}
}
then just call
shrinkwrap_vector(x);
in your code instead of x.shrink_to_fit()
. That would just copy your vector into a brand new vector that was as close to the size as your implementation would let you get.
Also note that if you're storing something that has a non-trivial destructor (double has a trivial destructor), that destructor will be called for every dropped element when you do a resize
. The whole shrink_to_fit
thing is solely about memory allocation, not about construction or destruction.
Lastly, if you really, really want to use the C malloc
and realloc
calls, you might be able to create a custom vector
class that uses those. You have to be extra careful though unless you make your custom class specific to double
. You have to call the constructor on any elements that are added after the memory is allocated and the destructor on any dropped elements before the memory is deallocated.
Writing this sort of class is complex. You need to conform to the expectation for container classes in C++ to make it work smoothly with everything else. This includes making iterator classes and things of that nature.