c++ Vector, what happens whenever it expands/reallocate on stack?

后端 未结 7 740
情深已故
情深已故 2020-11-29 00:51

I\'m new to C++ and I\'m using the vector class on my project. I found it quite useful because I can have an array that automatically reallocates whenever it is necessary (

相关标签:
7条回答
  • 2020-11-29 01:16

    If you make some growing vector, from empty, to some size, will be using doubling strategy, and most of the time reallocation, in this example using integer from 1 to 10000, and clang (std=2a -O3) will get this, this is just for fun, showing the importance of using reserve. vector::begin() point to beginning of actual array, and vector::capacity show actual capacity. In the other hand, iterator invalidated is showed.

    std::vector<int> my_vec;
    auto it=my_vec.begin();
    for (int i=0;i<10000;++i) {
        auto cap=my_vec.capacity();
        my_vec.push_back(i);
        if(it!=my_vec.begin()) {
            std::cout<<"it!=my_vec.begin() :";
            it=my_vec.begin();
        }
        if(cap!=my_vec.capacity())std::cout<<my_vec.capacity()<<'\n';
    }
    

    This produce the following result:

    it!=my_vec.begin() :1
    it!=my_vec.begin() :2
    it!=my_vec.begin() :4
    it!=my_vec.begin() :8
    it!=my_vec.begin() :16
    it!=my_vec.begin() :32
    it!=my_vec.begin() :64
    it!=my_vec.begin() :128
    it!=my_vec.begin() :256
    it!=my_vec.begin() :512
    it!=my_vec.begin() :1024
    it!=my_vec.begin() :2048
    it!=my_vec.begin() :4096
    it!=my_vec.begin() :8192
    it!=my_vec.begin() :16384
    
    0 讨论(0)
  • 2020-11-29 01:18

    The way you construct your vector (stack or heap) doesn't matter for this.

    See the documentation for std::vector

    Internally, vectors use a dynamically allocated array to store their elements. This array may need to be reallocated in order to grow in size when new elements are inserted, which implies allocating a new array and moving all elements to it.

    When a vector "grows", the vector object doesn't grow, only the internal dynamic array changes.

    As for its implementation, you can look at GCC's vector implementation.

    To keep it simple, it declares vector as a class with one protected member, of type _Vector_impl.

    As you can see, it is declared as a structure that contains three pointers :

    • One that points at the beginning of the storage (and the beginning of the data)
    • One that points at the end of the data
    • One for the end of the storage
    0 讨论(0)
  • 2020-11-29 01:26

    you also can reserve to reserve anticipated size,

    vect.reserve(10000);
    

    this will reserve 10000 object space of the type used

    0 讨论(0)
  • 2020-11-29 01:30

    A vector is not an array of elements, or the memory used to store such.

    A vector manages an array of elements, the memory for which it allocates, de-allocates, shrinks and grows as required.

    Your choice of how you allocate the vector itself has no connection to the vector's own decisions about how and where to allocate the memory it manages for you.

    I don't want to discourage your interest in how the vector works internally (it's both interesting and useful), but ... the whole point of writing classes and documenting them is that you only need to understand the interface, not the implementation.

    0 讨论(0)
  • 2020-11-29 01:31

    You are essentially asking about the implementation details of a vector. The C++ Standard does not define how a vector is to be implemented -- it only defines what a vector should do and what operations are required to be implemented. Nobody can tell you with 100% accuracy what happens when a vector is reallocated, because every compiler is theoretically different.

    That being said, it is not difficult to understand how a vector is typically implemented. The vector itself is simply a data structure which has a pointer to the actual data stored "in" the vector. Something along these lines:

    template <typename Val> class vector
    {
    public:
      void push_back (const Val& val);
    private:
      Val* mData;
    }
    

    The above is obviously psudocode, but you get the idea. When a vector is allocated on the stack (or on the heap):

    vector<int> v;
    v.push_back (42);
    

    The memory might end up looking like this:

    +=======+        
    | v     |
    +=======+       +=======+
    | mData | --->  |  42   |
    +=======+       +=======+
    

    When you push_back to a full vector, the data will be reallocated:

    +=======+        
    | v     |
    +=======+       +=======+
    | mData | --->  |  42   |
    +=======+       +-------+
                    |  43   |
                    +-------+
                    |  44   |
                    +-------+
                    |  45   |
                    +=======+
    

    ...and the vector's pointer to the new data will now point there.

    0 讨论(0)
  • 2020-11-29 01:34

    The vector object may well be instiantiated on the stack but the data within the vector will be on the heap.

    (The trivial class class foo {int* data;}; has this characteristic)

    0 讨论(0)
提交回复
热议问题