9

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

I'm reading the part where the book basically describes how to implement 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, size;
    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 of 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, size;
    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];
        delete[] elem;                 
        elem = p;
        space = newalloc;
    }
};
Boann
  • 48,794
  • 16
  • 117
  • 146
namcao00
  • 272
  • 1
  • 6
  • 10
  • Possible duplicate of [What's the advantage of using std::allocator instead of new in C++?](https://stackoverflow.com/q/31358804/608639) – jww Sep 21 '18 at 05:10

1 Answers1

15

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.
taskinoor
  • 45,586
  • 12
  • 116
  • 142
  • 1
    You might consider improving the canonical duplicate at [What's the advantage of using std::allocator instead of new in C++?](https://stackoverflow.com/q/31358804/608639) – jww Sep 21 '18 at 05:12
  • @jww looks like the duplicated one already contains better explanations than mine. – taskinoor Sep 21 '18 at 05:33