2016-12-29 88 views
0

发现这个代码,在做代码审查:传递指针代替迭代器的std ::复制

std::array<uint, 10> expArray2 = {92,130,169,951,634,187,377,233,865,944}; 
copy(&expArray2[0], &expArray2[10], back_inserter(expected)); 
         ^~~~Is this Undefined behavior as ArrayIndexOutOfBoundAccess? 

它是一样的(我的建议):

std::copy (expArray2, expArray2+10, expected.begin()); 

我的同事说,1。 )都是相同的2.)没有未定义的行为?

我向他解释,指针和迭代器是两个different的东西,用std::copy签名一起:

template <class InputIterator, class OutputIterator> 
  OutputIterator copy (InputIterator first, InputIterator last, OutputIterator result); 

可能有人请确认/这个给我解释如果我错了随时随地

+0

指针是一种迭代器。甚至在您提供的链接中提到了这一点。 – user2357112

+0

是的,但我主要关心的是arrayIndexOutOfBoundAccess。 –

+1

似乎这个问题的核心是关于'&expArray2 [10]'的表达。在这种情况下,这看起来相关:http://stackoverflow.com/questions/988158/take-the-address-of-a-one-past-the-end-array-element-via-subscript-legal-by- – TheUndeadFish

回答

0

你的同事是对的。

迭代器是一个带有需求的概念(它们可以被解除引用并且增加是最小的),指针充满了。

此外,C++中的范围是半开放的,这意味着传递给算法的第二个(最后一个)迭代器需要是一个过去要包含在该范围中的元素。它从来没有被解除引用(这是由C++标准保证的),所以没有UB代码。

注意:expected.begin()不等于back_inserter(expected)。对于前者,你需要一个足够大的容器来保存结果范围,而后者则会自动扩展它。

+0

您可能想对'back_inserter(expected)'与'expected.begin()'的使用进行评论。 – druckermanly

+0

@ user2899162做到了。你说得对,有点可疑。 – jrok

+0

我知道这种差异,矢量不提供大小之前。所以它确定。 –

1

This std ::复制使用std :: array是完全有效的。基本上std :: copy使用指示输入范围的指针,因为指针满足输入迭代器的所有要求。

至于服用开始端输入范围的& expArray2 [0]& expArray2 [10]也很好,因为的std ::阵列是保证管理连续的底层数组,所以你可以像处理任何常用的C风格的数组一样处理这个数组。

对我来说,我更愿意用的std ::开始的std ::结束的std ::复制

std::copy(std::cbegin(expArray2), std::cend(expArray2), 
    std::back_inserter(expected));