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

时间:2016-03-09 19:58:07

标签: c++ c++11 vector

其中一个std::vector构造函数被规定为强调我的:

  

explicit vector(size_type n, const Allocator& = Allocator());
  效果:使用指定的分配器构建vector n 默认插入元素。
  要求: T DefaultInsertable*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, '\0');

1 个答案:

答案 0 :(得分:9)

这是正确的行为。见23.2.1:

  

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

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

结论:

memset()是合适的。

结论#2

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