默认插入向量不是默认初始化吗?

Default-inserting into a vector isn't default initialization?

本文关键字:默认 初始化 插入 向量      更新时间:2023-10-16

>std::vector构造函数之一被规定为,强调我的:


explicit vector(size_type n, const Allocator& = Allocator()); 影响:使用指定的分配器构造包含n默认插入元素vector
需要: TDefaultInsertable *this.
复杂性:线性n .

默认

插入与默认初始化有任何关系吗?在此代码上:

std::vector<char> v(66000);

GCC 5.2 优化产生:

  400d18:   bf d0 01 01 00          mov    $0x101d0,%edi
  400d1d:   48 83 c5 01             add    $0x1,%rbp
  400d21:   e8 1a fd ff ff          callq  400a40 <operator new(unsigned long)@plt>
  400d26:   31 f6                   xor    %esi,%esi
  400d28:   48 89 c3                mov    %rax,%rbx
  400d2b:   ba d0 01 01 00          mov    $0x101d0,%edx
  400d30:   48 89 c7                mov    %rax,%rdi
  400d33:   e8 38 fc ff ff          callq  400970 <memset@plt>

memset在这里做什么?我认为这应该只是相当于new char[66000]......也就是说,没有初始化。Clang 3.7 也发出memset .

为什么这里有memset?就标准而言,这是否正确?毕竟,如果我想要 66000 个值初始化字符,我已经有了这个构造函数:

std::vector<char> v(66000, '');
这是

正确的行为。参见 23.2.1:

如果 X 的元素是通过计算表达式初始化的,则默认插入该元素allocator_traits<A>::construct(m, p)

比,allocator_traits<A>::construct会打电话给a.construct(p, std::forward<Args>(args)...).反过来,它调用::new((void *)p) U(std::forward<Args>(args)...),实际上调用new(),它进行值初始化。

结论:

memset()是恰当的。

结论 #2

如果没有自定义分配器,std::vector不允许人们选择访问未初始化的存储。每个合法地在向量中的对象都被值初始化了。