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;
}
};
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.
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.
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.
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:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With