Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

c++

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;
    }
};
like image 627
namcao00 Avatar asked Sep 21 '18 04:09

namcao00


People also ask

Does std::vector use new?

The std::vector<> is a container from the c++ Standard Template Library (STL) which has a number of features. It, however, fundamentally has the same basic underlying function as new[], which is allocating memory for a continuous sequence of object.

Does std::vector assign allocate?

As mentioned above, std::vector is a templated class that represents dynamic arrays. std::vector typically allocates memory on the heap (unless you override this behavior with your own allocator). The std::vector class abstracts memory management, as it grows and shrinks automatically if elements are added or removed.

What is std :: allocator?

std::allocator is the default memory allocator for the standard library containers, and you can substitute your own allocators. This allows you to control how the standard containers allocate memory.


1 Answers

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.
like image 178
taskinoor Avatar answered Oct 21 '22 05:10

taskinoor