7

Possible Duplicate:
What is the complexity of std::vector<T>::clear() when T is a primitive type?

If I have a std::vector with a primitive type, and I call clear() (this way push_back starts at the beginning of the capacity), is the clear() call going to be completed in constant time or linear time? The documentation says it destroys all the elements, but if the element is an int, there shouldn't be anything to destroy, right?


edit: I found a duplicate that has a poster who explains in detail that the implementation can check whether the destructor is trivial, and gives an example of one compiler that has that check (GCC).

What is the complexity of std::vector<T>::clear() when T is a primitive type?

Community
  • 1
  • 1
Mr. Smith
  • 4,288
  • 7
  • 40
  • 82

2 Answers2

5

It depends on how the vector is implemented, but an array of objects with trivial destructors (which includes PODs like built-in integral types such as int) should be able to be deallocated safely with a single call to vector<T>::allocator_type::deallocate without looping over the elements and individually invoking destructors. An implementation of std::vector can use type_traits or compiler internals to determine if T has a trivial destructor, and deallocate the internal array accordingly. You'll need to check the source code of your implementation to find out what it does, but most mainstream implementations of std::vector will give you constant-time deallocation for types with trivial destructors (or at least constant time for integral types and other PODs).

Charles Salvia
  • 52,325
  • 13
  • 128
  • 140
  • If allocation is not constant time? why would de-allocation be constant ? – Shiplu Mokaddim Dec 30 '12 at 20:29
  • Because deallocation can be implemented as a single operation if `T` has a trivial destructor. – Charles Salvia Dec 30 '12 at 20:30
  • See [this](http://en.cppreference.com/w/cpp/container/vector/clear) – Shiplu Mokaddim Dec 30 '12 at 20:31
  • @shiplu.mokadd.im, pushing an object may require to reallocate and copy all items. This is a linear time operation. If there's still free room in the vector, pushing an object is a constant-time operation. – zneak Dec 30 '12 at 20:31
  • @zneak in that case it depends on the size of container. – Shiplu Mokaddim Dec 30 '12 at 20:32
  • 3
    @shiplu.mokadd.im, that doesn't matter. That's just a guess or a generalization by whoever wrote the article on `cppreference.com`. It's not authoritative or a quote from the standard. The OP asked a question about *implementation* and the fact of the matter is that `std::vector` can be implemented with constant-time deallocation if `T` has a trivial destructor. – Charles Salvia Dec 30 '12 at 20:33
  • 2
    @shiplu.mokadd.im, _inserting_ in a vector is constant time if the reserved size is larger than the number of elements, so it does depend on two variables. Clearing, on the other hand, doesn't depend on either the actual size or reserved size of the vector. It's a linear-time operation if you have to call destructors. But if you only have trivial destructors to call (for instance, with an `int` vector), it's possible to optimize the implementation of the vector to skip that step. If you can, the clear operation effectively becomes constant-time, as Charles explained. – zneak Dec 30 '12 at 20:36
  • @zneak See 23.1.1 [here](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1905.pdf). More clearly on 23.1 in table 72. – Shiplu Mokaddim Dec 30 '12 at 20:54
  • 1
    @shiplu.mokadd.im 17.1.3.3 clause 5: "Complexity requirements specified in the library clauses are upper bounds, and implementations that provide better complexity guarantees satisfy the requirements." – zneak Dec 30 '12 at 22:04
2

The standard makes no guarantees about the complexity of std::vector::clear, though you'd expect the operation to be linear in the container's size for complex element types, and constant for PODs.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055