简体   繁体   中英

How does std::vector allocate objects?

How does std::vector allocate objects? It would seem as if it just uses std::allocator::allocate to create a block of memory, but then never calls std::allocate::construct . Is this true? Does std::vector only allocate memory and never construct the objects as memory allocation?

What if there is no default constructor? How is the constructor called when there is no default constructor on the object? What if there is more than one parameter?

For example, with this code there is no default constructor and std::allocator allows it.

#include <vector>
using namespace std;

class A{
protected:
    int m;
public:
    explicit A(int a) : m(a) { }
};

int main(){
    vector<A> test;
    return 0;
}

This has rather changed since C++11.

In C++03, construct could only perform copy-construction in-place.

However, note that std::vector in particular is an array of objects, but there is a distinct size and capacity. That is, there can be more empty elements beyond the end of the part of the array that contains useful data.

That is why the standard library's allocator has a separation between "construction" and "memory allocation." The allocator does do both, but not at the same time . This allows std::vector to allocate more memory than it uses. When you add new elements, it doesn't necessarily have to allocate more memory; it can just use the spare memory it has left over via a call to allocator::construct .

Also, note that all of the C++03 functions that add elements to std::vector take an element as a parameter. push_back , insert , even the sized constructor takes as a value as an argument . Yes, it's a default parameter, but it still takes a value as an element. This element is copied into the vector, using a call to the allocator's construct method which takes a copy.

In C++11, standard containers are required to use the allocator_traits<>::construct function. This is a varadic function that forwards its parameters to the actual construct. This traits function will (by default. It can be specialized) call the allocator::construct method if that call is well-formed. If it isn't, it will try placement new .

This allows for the new emplace functions to work.

But yes, the objects contained in standard library containers are in fact constructed objects. Even if the allocator's construct method is not called.

It's implementation dependent, but a typical implementation uses std::allocator::allocate to allocate the block of memory, and then uses the placement new to construct, via the copy constructor (or move constructor in C++11), the instances.

When elements are erased, their destructors are directly invoked to destroy the objects, even if the underlying memory isn't released.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM