【问题标题】:Why does std::vector use std::allocator instead of operator new and delete? [duplicate]为什么 std::vector 使用 std::allocator 而不是 operator new 和 delete? [复制]
【发布时间】:2019-02-25 10:41:27
【问题描述】:

我正在阅读该语言作者的《Programming Principle and Practices using 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,因为vector的数据结构是由一些初始化的数据和一些未初始化的数据组成的。

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

【问题讨论】:

标签: c++


【解决方案1】:

如果我使用 new 和 delete 会出现什么问题?

T* p = new T[newallow];

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

分配器的基本思想是将分配内存和对象构造的步骤分开。默认new 结合了两者。在vectorreserve 的情况下,我们只想分配所需的内存。我们当时无法构造或初始化对象,因为该类型可能不是默认可构造的。只有当我们将对象传递给存储在其他操作中时,才能稍后构造对象,例如

v[i] = myObj;

如果不将内存分配和对象构造分为两个不同的步骤,这是无法实现的。

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

书中提到我们必须使用std::allocator,因为vector的数据结构由一些初始化数据和一些未初始化数据组成。

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

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

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2020-07-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-05
  • 1970-01-01
  • 1970-01-01
  • 2019-08-22
相关资源
最近更新 更多