4

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!

braX
  • 11,506
  • 5
  • 20
  • 33
Ross Allen
  • 463
  • 1
  • 5
  • 11
  • Relevant reading: http://stackoverflow.com/questions/10464992/c-delete-vector-objects-free-memory . Yes, you are likely to cause leaks, but since they're on the stack, it might not matter. – CollinD Feb 08 '16 at 06:03
  • 1
    There's never any safety issue, vectors do not leak memory. – M.M Feb 08 '16 at 07:22

2 Answers2

5

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.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
2

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.

Shoe
  • 74,840
  • 36
  • 166
  • 272