Ross Allen
Ross Allen

Reputation: 483

C++ - Best practice for overwriting/reconstructing entire std::vector

If I have an std::vector that I want to completely overwrite (not just resize). What is the safest way to do this in terms of memory management? For example

int main() {
    std::vector<float> X (5, 5.0);
    X = std::vector<float> (6, 6.0);
    X = std::vector<float> (4, 4.0);
}

will create a vector of 5 floats of value 5.0. Then it will overwrite it with a vector of size 6 with values 6.0, then overwrite with a vector of size 4 with values 4.0. If I'm performing this type of operation an indefinite number of times, are there risks of corrupting or leaking memory with this approach? Should I be using clear() before each overwrite? Is there a more efficient way to achieve this?

I'm sure this question has been asked many times but Google isn't pulling up the exact scenario I am looking for.

Thanks!

Upvotes: 5

Views: 12691

Answers (2)

Nicol Bolas
Nicol Bolas

Reputation: 474076

std::vector has specific member functions for doing exactly this. Allocators and copy/move aside, each of vector's constructors has a corresponding overload of assign that does the same thing. So if you want to reuse the vector's storage, just use it:

std::vector<float> X (5, 5.0);
X.assign(6, 6.0);
X.assign(4, 4.0);

Of course, there is no guarantee that vector implementations won't reallocate memory. However, that would be a really stupid implementation.

Upvotes: 6

Shoe
Shoe

Reputation: 76280

are there risks of corrupting or leaking memory with this approach?

Nope.

Should I be using clear() before each overwrite?

It's not necessary.

Is there a more efficient way to achieve this?

It highly depends on the pattern in which you keep replacing the vector. In your current code, a new vector is allocated, then the old one is deallocated and the new one is moved into X each time.

Allocating and deallocating are costly operations. It would be probably a better idea to just loop over the vector and change each already existing element and/or push new elements into the existing vector. Along the lines of:

std::vector<float> X (5, 5.0);

std::transform(begin(X), end(X), begin(X), [](int){ return 6.0; }); 
X.resize(6, 6.0);

std::transform(begin(X), end(X), begin(X), [](int){ return 4.0; }); 
X.resize(4);

This may result in slower code if the number of elements is high and the objects are not simple integers.

The best way to check that out is to actually write both versions and benchmark them.

Upvotes: 3

Related Questions