Why does std::vector uses std::allocator instead of operator new and delete [duplicate]

  • A+
Category:Languages

This question already has an answer here:

I'm reading the book "Programming Principle and Practices using C++" by the author of the language.

I'm reading to the part where the book basically describe how to implement the std::vector. And here's a piece of code in the book:

template<typename T, typename A = std::allocator<T>> class vector {     A alloc;     int space;     T* elem;     //...some code     reserve(int newalloc) {         if (newalloc <= space) return;               // never decrease allocation                T* p =  alloc.allocate(newalloc);          // allocate new space                   for (int i = 0; i < sz; ++i) alloc.construct(&p[i], elem[i]);       // copy                  for (int i = 0; i < sz; ++i) alloc.destroy(&elem[i]);                 // destroy                  alloc.deallocate(elem, space);             // deallocate old space                  elem = p;         space = newalloc;     } }; 

The book mentions that we have to use std::allocator because the vector's data structure consists some initialized data and some uninitialized data.

I'm not clear what that means. What could go wrong if I use new and delete?

template<typename T> class vector2 {     A alloc;     int space;     T* elem;     //some code     reserve(int newalloc) {         if (newalloc <= space) return;                              T* p = new T[newallow];               for (int i = 0; i < sz; ++i) p[i] = elem[i];         for (int i = 0; i < sz; ++i) delete[] elem;                          elem = p;         space = newalloc;     } }; 

 


What could go wrong if I use new and delete?

T* p = new T[newallow]; 

One reason is that this won't compile if T doesn't have default constructor.

The basic idea of allocator is to separate the steps of allocating memory and object construction. Default new combines the both. In case of vector reserve we only want to allocate the required memory. We can't construct or initialize the objects at that time since the type may not be default constructible. The objects can be constructed later only when we pass the objects to store in some other operation, e.g.

v[i] = myObj; 

This can't be achieved without separating memory allocation and object construction in two different steps.

Also note that, allocator have advanced usages when someone wants to customize the memory allocation.

The book mentions that we have to use std::allocator because the vector's data structure consists some initialized data and some uninitialized data.

What author meant here is that while growing the capacity by calling reserve we will have two types of data:

  1. Existing objects in the vector which needs to be moved to new space. They are initialized data.
  2. Extra reserved space which doesn't store any object yet and thus uninitialized.

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: