2

What would be the difference between:

std::vector::erase

and

std::vector::clear

What I want to do is to get rid of all elements, positions, including memory addresses and having no exception thrown.

vector<array<double,1000>> S1(1000);

I would like at the end to get rid of the 1000*2 created memory addresses.

MelMed
  • 255
  • 10
  • 19
  • possible duplicate of [Difference between erase and remove](http://stackoverflow.com/questions/799314/difference-between-erase-and-remove) – Vijay Jun 24 '13 at 08:30
  • Perhaps have a look at [a good reference](http://en.cppreference.com/w/cpp/container/vector). It sounds like you want to call ``clear()``. – juanchopanza Jun 24 '13 at 08:31
  • 3
    @Vijay ``remove`` != ``clear``. – juanchopanza Jun 24 '13 at 08:31
  • @Vijay no sorry, I was well clear, about the different between ERASE and CLEAR, and not ERASE and REMOVE. – MelMed Jun 24 '13 at 08:34
  • 1
    @juanchopanza The allocated memory will not be released with Clear apparently. But I do want to release the memory. – MelMed Jun 24 '13 at 08:37
  • @MelMed Good point. Then you need to perform the ``swap`` trick: ``std::vector().swap(myOldVector);`` – juanchopanza Jun 24 '13 at 08:39
  • @MelMed What allocated memory, that of the `vector`? `erase` won't do that either, you have to use the swap-trick for that (or in C++11 `std::vector::shrink_to_fit`, but even that is not guaranteed to work). Though, *"get rid of all elements, positions, including memory addresses"* sounds a bit weird and I hope you're not after deleting dynamically allocated objects stored in the vector. – Christian Rau Jun 24 '13 at 08:42
  • @ChristianRau He gives `std::vector>` as the type, so there shouldn't be any pointers. (His last sentence sounds weird to me, too.) – James Kanze Jun 24 '13 at 08:45
  • 1
    *"I would like at the end to get rid of the 1000*2 created pointers."* - There are no 1000*2 pointers in a `vector>(1000)`, where did you get this idea from? There are just 1000 `std::array`s in it, nothing else (and those won't contain any pointers either). – Christian Rau Jun 24 '13 at 08:45

5 Answers5

4

erase gets rid of elements selectively by position. clear gets rid of all elements unconditionally, and can be considered syntactic sugar for a call to v.erase(v.begin(),v.end());

Benjamin Lindley
  • 101,917
  • 9
  • 204
  • 274
2

The only sure way to release the memory that I can think of is to swap with a temporary vector:

vector<array<double,1000>> S1(1000);
...
vector<array<double,1000>>().swap(S1);

Although this might look strange at first, it is a known, widely used idiom.

In C++11, moving from the original vector might be an option, although it is not guaranteed to clear the memory or even clear the vector (I cannot think of a reason why an implementation wouldn't do that though):

{
  vector<array<double,1000>> tmp(std::move(S1));
} // tmp dies on exiting scope, memory is cleared

Altenratively, a call to std::vector::shrink_to_fit could result in memory de-allocation, but there are no guarantees:

S1.clear();
S1.shrink_to_fit();
juanchopanza
  • 223,364
  • 34
  • 402
  • 480
  • In C++11, `std::vector` has a `shrink_to_fit` member, which _should_ be the best solution. (The standard doesn't guarantee much in this regard, but QoI should mean that it works.) – James Kanze Jun 24 '13 at 08:46
  • And the solution with `move` looks more like obfuscation than anything else to me. – James Kanze Jun 24 '13 at 08:48
  • @JamesKanze *"The standard doesn't guarantee much in this regard"* - And that's the problem why it is a completely rubbish function. Of course an implementation would be stupid not to implement `shrink_to_fit` properly, but that's not what the standard guarantees. It's like saying *"here you have fixed width integer types, except when you haven't"*. Though I agree that the move-solution is counter-intuitive. – Christian Rau Jun 24 '13 at 08:49
  • @JamesKanze I added a line about ``shrink_to_fit``. I think the swap trick is the only guaranteed method, but it still does look like a bit of hack to me. – juanchopanza Jun 24 '13 at 08:50
  • Though the answer got accepted, from his rather strangely worded question I have the strong feeling the OP didn't nearly understand what is going on and what he really needs to do. – Christian Rau Jun 24 '13 at 08:51
  • @JamesKanze As for the move solution, I guess it is a matter of familiarity. We're probably used to the swap trick, and I would naturally opt for that solution, but I have seen it confuse the heck out of newcomers to C++. – juanchopanza Jun 24 '13 at 08:53
  • +1. It may be worth mentioning that `clear()` has a `noexcept` guarantee (which is possible because the destructors of vector elements are required to be destructible without exceptions). `erase()` doesn't have that guarantee because in theory it could trigger moves/copies (of course it won't do that when you delete _all_ elements). `shrink_to_fit`, for some reason, isn't `noexcept` either. – jogojapan Jun 24 '13 at 08:56
  • "moving from" doesn't really work out well, since the vector is then only capable of being destroyed, not of being reused. – PlasmaHH Jun 24 '13 at 08:56
  • @PlasmaHH That is entirely wrong. The assumption that you can only destroy moved-from objects is a common misunderstanding. In general a moved-from object is in a *valid but unspecified state*, so you can do whatever you want with it that doesn't require preconditions, like e.g. `=`, `clear` or `empty` (otherwise the default `std::swap` wouldn't even work). See [this question](http://stackoverflow.com/q/7027523/743214). Though I'm not sure the standard guarantees the moved-from vector to be empty, but even then it wouldn't guarantee it to deallocate its storage. – Christian Rau Jun 24 '13 at 09:16
  • @ChristianRau I don't think there is any guarantee the vector will be cleared, let alone its memory de-allocated. – juanchopanza Jun 24 '13 at 09:19
  • @juanchopanza Maybe even the former but most definitely not the latter, which makes it useless for freeing, anyway. But the statement that you can only destroy it was rubbish nevertheless. – Christian Rau Jun 24 '13 at 09:20
  • @ChristianRau I think that the intent is clear, and there are so many things the standard doesn't guarantee. Am implementation can, for example, create a vector with a capacity of 1000 when the default constructor is invoked. (In this case, I suspect that the weasel wording in the standard is for cases where memory allocation has very strict alignment requirements, and the implementation of vector ensures that capacity is always a multiple of these.) – James Kanze Jun 24 '13 at 10:07
  • @jogojapan The exception issue is well spotted. And `shrink_to_fit` can't have a `noexcept` guarantee, since it may have to reallocate and copy elements. (And I agree that there is nothing intuitive about the swap idiom. It's just one of those recognized patterns.) – James Kanze Jun 24 '13 at 10:12
  • @JamesKanze Ah right. `shrink_to_fit` isn't `noexcept` because of the same reason why `erase` isn't. I should have seen that.. Anyway. All is clear now. – jogojapan Jun 24 '13 at 10:15
  • 1
    @jogojapan It's worse that `erase`, actually. The only reason `erase` can throw is if the copy constructor or assignment operator of `T` throws (so it cannot throw on `std::vector`). `shrink_to_fit` also requires an allocation, which can also fail. – James Kanze Jun 24 '13 at 10:19
0

Erase lets you specify begin and end positions whereas clear clears the whole Vector.

http://www.cplusplus.com/reference/vector/vector/erase/

http://www.cplusplus.com/reference/vector/vector/clear/

Denis
  • 165
  • 1
  • 1
  • 12
0

The function clear() empties the vector. The function erase() removes selective elements (there are several overloads). erase(v.begin(), v.end()); is equivalent to calling clear();. The created memory will still be reserved for possible future use. If you want to be sure to free all this memory, then call v.clear(); and then v.shrink_to_fit(), if you have a C++11 compiler. (There's no actual guarantee that the memory will be freed, it's just a request, but I don't know of any compiler which doesn't free the memory.) If you don't have C++11 compliance then use the alternative std::vector<std::array<double,1000>>().swap(v);. That's called the shrink to fit idiom.

Ralph Tandetzky
  • 22,780
  • 11
  • 73
  • 120
0

v.erase(v.begin(),v.end()) is equivalent to v.clear() where v is an object of any vector. Here clear will be used for delete all the vector elements but erase can we used to delete any specific element or range of element.