Re: std::vector::clear (was: [GD-Windows] VS.net rants, was Re: VC++ lag)
Brought to you by:
vexxed72
From: Neil S. <ne...@r0...> - 2003-06-14 01:28:37
|
> It sounds to me like you were relying on an implementation dependency. > My copy of "C++ Standard Library" by Josuttis just says that both of > these will remove all the elements of the vector. AFAIK, the standard > makes no requirements about allocation/deallocation behavior for these > operations, but I would expect both to potentially deallocate memory > when I delete the whole vector. If you want to clear the vector > without changing its allocation, you should do vector::resize(0) IMO. I don't agree with this, for several reasons: 1. The standard says that clear() is simply erase(begin(), end()), with a post-condition of size()==0. It does not say that you can implement it any other way, and this implementation (a Dinkumware variant) does exactly that: it calls _Tidy(), so it is not following the standard on that score. 2. While the standard does not appear to say that erase() must not deallocate memory, it very explicitly states that insert() will allocate memory if required, and it is also very clear that resize() and reserve() should never reduce capacity() (i.e. deallocate memory). In other words, I believe the standard tells you what *will* happen during any operation and if it does not mention something, it means that it *will not* happen, not that "anything goes". You would have to be pretty anal to take this any other way, which is what I think Dinkumware have done. 3. Stroustrup says explicitly in "The C++ Programming Language" that a vector will never shrink, only grow. If the standard disagrees with this, then why, and why is it still in his book? 4. It is far more consistent to make erase() (and therefore clear(), due to point 1) operate in exactly the same manner as everything else in the vector, including reserve() and resize(), none of which reduce the memory used by the vector(). Every implementation I have seen does indeed treat erase() in the same, consistent manner, and only the Dinkumware one differs when it comes to clear(). It seems that everyone else has read the standard to mean that a vector will not shrink. 5. The original Dinkumware STL used in VC6 uses erase(begin(), end()), and is consistent with everything else in this respect. The fact that they have since changed this defies belief. The only reason I can think of is that they observed that many programmers were wasting a lot of memory on vectors and thought they could "optimise" applications by making clear() deallocate. The ironic thing is that they have actually hurt a lot of applications that were relying on non-deallocation for performance reasons. 6. From an implementation perspective, there is very little to gain from deallocating on clear() because you cannot assume that it *will* deallocate on all implementations, so you must always use other methods (e.g. swap()) to ensure deallocation when you require it. All they have achieved is to change the performance characteristics of the STL, which is deplorable, because clearly defined performance characteristics are one of the main features of the library. 7. Every implementation I have ever seen maintains capacity() on a clear(). For Dinkumware to say "sod what every other implementation has done for years" is quite offensive in my book and is another reaosn people will be able to spout about not using the STL. They have actually *damaged* standard C++ by doing this. The standard _may_ be unclear on this situation, but common practice is not so, if in doubt, they should have stuck with that. 8. Many, many people (including Stroustrup, it would appear) work on the assumption that no STL implementation ever deallocates on a clear(). Even if Dinkumware could argue that the standard does not actually say this, they cannot ignore the fact that a lot of people are assuming that this is the case. Doing so was very irresponsible IMO. I could go on, but I think the important point is that Dinkumware have done *no good* by taking this step, and clear() should be changed back to its original form in future releases. - Neil. |