3

Lets say if I have a vector V, which has 10 elements. If I erase the first element (at index 0) using v.erase(v.begin()) then how STL vector handle this?

Does it create another new vector and copy elements from the old vector to the new vector and deallocate the old one? Or Does it copy each element starting from index 1 and copy the element to index-1 ?

If I need to have a vector of size 100,000 at once and later I don't use that much space, lets say I only need a vector of size 10 then does it automatically reduce the size? ( I don't think so)

I looked online and there are only APIs and tutorials how to use STL library. Is there any good references that I can have an idea of the implementation or complexity of STL library?

genpfault
  • 51,148
  • 11
  • 85
  • 139
codereviewanskquestions
  • 13,460
  • 29
  • 98
  • 167
  • 3
    [Effective STL](http://www.amazon.ca/Effective-STL-Specific-Standard-Template/dp/0201749629), by Scott Meyers, is a really good one for STL. As seen in the [faq book list](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list), [C++ Standard Library Tutorial and Reference](http://www.amazon.com/dp/0321623215/?tag=stackoverfl08-20) looks like it could help too. – chris Jun 13 '12 at 22:17
  • 1
    In general, [it's not called STL](http://stackoverflow.com/questions/5205491/whats-this-stl-vs-c-standard-library-fight-all-about/5205571#5205571). The C++ Standard Library, which you probably mean, is described in C++ Standard; you can obtain free copy of latest draft [here](https://github.com/cplusplus/draft). – Griwes Jun 13 '12 at 22:19
  • Well, I suppose that it doesn't deallocate memory with v.erase(v.begin()). Anyway you can use v.capacity() to test if the library changes the size of the allocated memory. – Vittorio Patriarca Jun 13 '12 at 22:20
  • Related SO question: http://stackoverflow.com/questions/2096571/how-is-c-stl-vector-implemented – kol Jun 13 '12 at 22:21
  • 2
    There are many STL implementations, and you can browse many of their sources online. SGI's is available, GNU's, and many others. – Nick Veys Jun 13 '12 at 22:22

5 Answers5

5

Actually, the implementation of vector is visible, since it's a template, so you can look into that for details:

iterator erase(const_iterator _Where)
    {   // erase element at where
    if (_Where._Mycont != this
        || _Where._Myptr < _Myfirst || _Mylast <= _Where._Myptr)
        _DEBUG_ERROR("vector erase iterator outside range");
    _STDEXT unchecked_copy(_Where._Myptr + 1, _Mylast, _Where._Myptr);
    _Destroy(_Mylast - 1, _Mylast);
    _Orphan_range(_Where._Myptr, _Mylast);
    --_Mylast;
    return (iterator(_Where._Myptr, this));
    }

Basically, the line

unchecked_copy(_Where._Myptr + 1, _Mylast, _Where._Myptr);

does exactly what you thought - copies the following elements over (or moves them in C++11 as bames53 pointed out).

To answer your second question, no, the capacity cannot decrease on its own.

The complexities of the algorithms in std can be found at http://www.cplusplus.com/reference/stl/ and the implementation, as previously stated, is visible.

Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625
  • I never thought I'd see you making a reference to that site. The good one has complexities too. – chris Jun 13 '12 at 22:22
  • 6
    To be pedantic: *an* implementation of `vector` is visible. There is more than one implementation. – GManNickG Jun 13 '12 at 22:23
  • 2
    @GManNickG And to be pedantic on your pedantry - *all* implementations are visible, but they're not necessarily identical to this one. :) I think that's what you meant. – Luchian Grigore Jun 13 '12 at 22:25
  • 1
    @LuchianGrigore: Fair enough. To up the pedantry, all *current* implementations *happen* to be visible; there needn't necessarily be any implementation of `vector` written in C++ code. :) – GManNickG Jun 13 '12 at 22:48
1

Does it copy each element starting from index 1 and copy the element to index-1 ?

Yes (though it actually moves them since C++11).

does it automatically reduce the size?

No, reducing the size would typically invalidate iterators to existing elements, and that's only allowed on certain function calls.

I looked online and there are only APIs and tutorials how to use STL library. Is there any good references that I can have an idea of the implementation or complexity of STL library?

You can read the C++ specification which will tell you exactly what's allowed and what isn't in terms of implementation. You can also go look at your actual implementation.

bames53
  • 86,085
  • 15
  • 179
  • 244
1

Vector will copy (move in C++11) the elements to the beginning, that's why you should use deque if you would like to insert and erase from the beginning of a collection. If you want to truly resize the vector's internal buffer you can do this:

vector<Type>(v).swap(v);

This will hopefully make a temporary vector with the correct size, then swaps it's internal buffer with the old one, then the temporary one goes out of scope and the large buffer gets deallocated with it.

As others noted, you may use vector::shrink_to_fit() in C++11.

CodingRecipes
  • 11
  • 1
  • 1
  • 3
0

That's one of my (many) objection to C++. Everybody says "use the standard libraries" ... but even when you have the STL source (which is freely available from many different places. Including, in this case, the header file itself!) ... it's basically an incomprehensible nightmare to dig in to and try to understand.

The (C-only) Linux kernel is a paragon of simplicity and clarity in contrast.

But we digress :)

Here's the 10,000-foot answer to your question:

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

Vector containers are implemented as dynamic arrays; Just as regular arrays, vector containers have their elements stored in contiguous storage locations, which means that their elements can be accessed not only using iterators but also using offsets on regular pointers to elements.

But unlike regular arrays, storage in vectors is handled automatically, allowing it to be expanded and contracted as needed.

Vectors are good at:

  • Accessing individual elements by their position index (constant time).
  • Iterating over the elements in any order (linear time).
  • Add and remove elements from its end (constant amortized time).

Compared to arrays, they provide almost the same performance for these tasks, plus they have the ability to be easily resized. Although, they usually consume more memory than arrays when their capacity is handled automatically (this is in order to accommodate extra storage space for future growth).

Compared to the other base standard sequence containers (deques and lists), vectors are generally the most efficient in time for accessing elements and to add or remove elements from the end of the sequence. For operations that involve inserting or removing elements at positions other than the end, they perform worse than deques and lists, and have less consistent iterators and references than lists.

...

Reallocations may be a costly operation in terms of performance, since they generally involve the entire storage space used by the vector to be copied to a new location. You can use member function vector::reserve to indicate beforehand a capacity for the vector. This can help optimize storage space and reduce the number of reallocations when many enlargements are planned.

...

paulsm4
  • 114,292
  • 17
  • 138
  • 190
  • It's not incomprehensible if you have a good reference. Each container has its advantages and disadvantages, and like any set of tools, needs to be understood before being applied to a problem. – tadman Jun 14 '12 at 05:44
-1

I only need a vector of size 10 then does it automatically reduce the size?

No it doesn't automatically shrink.
Traditionally you swap the vector with a new empty one: reduce the capacity of an stl vector

But C++x11 includes a std::vector::shrink_to_fit() which it does it directly

Community
  • 1
  • 1
Martin Beckett
  • 94,801
  • 28
  • 188
  • 263