为什么 std::vector 使用 std::分配器而不是运算符 new 和 delete?
Why does std::vector use std::allocator instead of operator new and delete?
>我正在阅读该语言作者的"使用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;
}
};
如果我使用 new 和 delete 会出什么问题?
T* p = new T[newallow];
一个原因是,如果T
没有默认构造函数,则不会编译。
分配器的基本思想是将分配内存和对象构造的步骤分开。默认new
将两者结合起来。在vector
保留的情况下,我们只想分配所需的内存。当时我们无法构造或初始化对象,因为该类型可能不是默认可构造的。只有当我们在其他操作中传递要存储的对象时,才能在以后构造对象,例如
v[i] = myObj;
如果不在两个不同的步骤中分离内存分配和对象构造,就无法实现这一点。
另请注意,当有人想要自定义内存分配时,分配器具有高级用法。
书中提到我们必须使用 std::allocator,因为向量的数据结构由一些初始化的数据和一些未初始化的数据组成。
作者的意思是,在通过调用reserve
来增加容量的同时,我们将拥有两种类型的数据:
- 矢量中需要移动到新空间的现有对象。它们是初始化的数据。
- 额外的保留空间,尚未存储任何对象,因此未初始化。
相关文章:
- 体系结构x86_64的未定义符号:std:terminate(),typeinfo,运算符delete[],运算符new
- 为什么 std::make_shared 无法编译带有已删除运算符 new 的类型?
- 为什么 std::vector 使用 std::分配器而不是运算符 new 和 delete?
- new(std::nothrow) int[n] 抛出异常
- C++ std::字符串语法 "new (&y) std::string(x);"
- std :: vector new的记忆不足
- Linux g++ new (std::nothrow) 确实有效
- 访问std :: MAP中的静态构造函数New New拨号
- C++ std::vector<> vs new[] 性能
- 使用 "new ClassType(std::move(/*class_object*/))" 在自由存储中构造对象
- new(std::nothrow)而不是new和错误处理
- 如何使用new(std::nothrow)使构造函数失败
- std::shared_ptr 初始化:make_shared<Foo>() vs shared_ptr<T>(new Foo)
- new int[size] vs std::vector
- 我似乎无法将MS泄漏检测器用于新表达式“new(std::nothrow)”.是这样吗
- 为具有已替换运算符new的类自定义std::分配器
- 为什么C++不需要"new"语句来初始化 std::vector?
- 在标准中哪里说' new '返回的每个分配都对齐到' std::max_align_t '
- 如何生成和使用c++11中的std::数组,使用new来使用堆而不是堆栈
- std::make_shared(new Foo())是否创建单例?