c – 为什么std :: vector使用std :: allocator而不是operator new和delete?

参见英文答案 > What’s the advantage of using std::allocator instead of new in C++?7个
我正在阅读该语言作者的“使用C编程原理和实践”一书.

我正在阅读本书基本描述如何实现std :: vector的部分.这是本书中的一段代码

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;
    }
};

书中提到我们必须使用std :: allocator,因为向量的数据结构包含一些初始化数据和一些未初始化的数据.

我不清楚这意味着什么.如果我使用new和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;
    }
};

解决方法

What could go wrong if I use new and delete?

T* p = new T[newallow];

一个原因是如果T没有默认构造函数,这将无法编译.

分配器的基本思想是分离分配内存和对象构造的步骤.默认新组合两者.在矢量保留的情况下,我们只想分配所需的内存.我们不能在那时构造或初始化对象,因为类型可能不是默认可构造的.只有当我们传递对象以存储在某些其他操作中时,才可以构造对象.

v[i] = myObj;

如果不在两个不同的步骤中分离内存分配和对象构造,则无法实现这一点.

另请注意,当有人想要自定义内存分配时,分配器具有高级用法.

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

作者在这里的意思是,通过调用reserve来增加容量,我们将有两种类型的数据:

>向量中需要移动到新空间的现有对象.它们是初始化数据.>额外保留空间,不存储任何对象,因此未初始化.

相关文章

/** C+⬑ * 默认成员函数 原来C++类中,有6个默认成员函数: 构造函数 析构函数 拷贝...
#pragma once // 1. 设计一个不能被拷贝的类/* 解析:拷贝只会放生在两个场景中:拷贝构造函数以及赋值运...
C类型转换 C语言:显式和隐式类型转换 隐式类型转化:编译器在编译阶段自动进行,能转就转,不能转就编译...
//异常的概念/*抛出异常后必须要捕获,否则终止程序(到最外层后会交给main管理,main的行为就是终止) try...
#pragma once /*Smart pointer 智能指针;灵巧指针 智能指针三大件//1.RAII//2.像指针一样使用//3.拷贝问...
目录&lt;future&gt;future模板类成员函数:promise类promise的使用例程:packaged_task模板类例程...