Release memory of std::vector in VC++ 2019

Viewed 160

I've recently started upgrading my current projects from VS2015 to VS2019 and VS2019 is a lot more restrictive about some things. One thing I have an issue with in particular is the way I'm currently releasing the memory of vectors:

std::vector<int> v(10);
v.swap(std::vector<int>()); // v should now be empty with no memory held

This worked fine in VS2015 but in VS2019 it no longer works because the vector I swap with is constant and vector::swap() requires a reference. This behavior has changed recently and must be a problem for more people than me given that this is the recommended way of releasing the memory of a vector. MS docs on the issue: https://docs.microsoft.com/en-us/cpp/error-messages/compiler-errors-2/compiler-error-c2664?view=msvc-160

What is the new recommended way of releasing the memory of a vector if you can't swap it away?

2 Answers

Your doing it backwards. To clear and release the memory for a vector in a guaranteed way, declare a temporary vector and swap the vector that needs to be cleared into it. That would tun your code into

std::vector<int>{}.swap(v);

At the end of the expression, the temporary object will be destroyed, taking the memory of v with it.


The reason this work before is Microsoft had an evil extension that was on by default that allowed prvalues to bind to non-const lvalue references. With that extension no longer on, the old non-standard code is now rightly failing to compile.

vector I swap with is constant

It's not constant, but it's an anonymous temporary, so it can only bind to a const ref.

What is the new recommended way of releasing the memory of a vector if you can't swap it away?

Well, you can swap it away, if you want to stay backwards compatible and/or don't trust shrink_to_fit(). You just have to name your temporary:

{
  std::vector<int> tmp;
  v.swap(tmp);
}

(obviously the reversed anonymous swap in the other answer is neater, if you don't need to stay backwards-compatible with C++98).

Related