在C ++ 11中获取std :: vector :: operator [](size)的未定义行为的地址

时间:2014-11-21 20:07:00

标签: c++ c++11

这是未定义的行为吗?

ptrdiff_t one() {
   std::vector<int> test(1);
   return &test[1] - &test[0];
}

这是未定义的行为吗?

ptrdiff_t zero() {
   std::vector<int> test;
   int * end = &test[0];
   int * begin = &test[0];
   return end - begin;
}

如果其中任何一个都是未定义的行为,任何人都可以帮我找到C ++ 11规范中的部分,它描述了向量的下标运算符必须在小于(而不是小于或等于)的值上调用尺寸,反之亦然?

由于

1 个答案:

答案 0 :(得分:6)

是的,这些程序片段有不确定的行为。

表101将test[0]定义为*(test.begin() + 0),如果您没有元素,则无效:

  

[C++11: 24.2.1/5]:正如指向数组的常规指针一样,保证指针值指向数组的最后一个元素,因此对于任何迭代器类型,都有一个指向超过最后一个元素的迭代器值。相应的序列。这些值称为 past-the-end 值。定义了表达式i的迭代器*i的值称为 dereferenceable 图书馆永远不会假定过去的价值是可解除引用的。 [..]

表106列出了解除引用性作为*i有效性的先决条件,给定任何迭代器i

之后您尝试接收地址并不重要:您已经破坏了您的计划。例如,对于任何过去的迭代器,您的标准库实现可以顺从地触发operator*的断言。