测试指针之间的关系以进行迭代是否安全?

时间:2019-06-14 11:38:53

标签: c pointers iteration

请考虑一个Thing数组。这是一种堆栈。

它由thingsBottom指向,其空端由thingsTop指向。

编辑:每次我想将某些内容推送到列表中时,我都会执行*thingsTop = newThing; thingsTop++;

我想使用指针从头到尾进行迭代,如下所示:

for (Thing* thing = thingsTop - 1; thing >= thingsBottom; thing--) {
    doSomething(*thing);
}

无论使用哪种特定的C实现,是否都能保证始终工作?

thing >= thingsBottom安全吗?

2 个答案:

答案 0 :(得分:5)

  

这可以保证始终运行,而不管特定的C   实施?

     

thing >= thingsBottom安全吗?

不是,不是无条件的。

您的方法的问题在于,它会产生未定义的行为来计算指针值,该值将在该指针所基于的数组的开始之前,并且指针比较仅对进入或刚刚结束的指针有效相同的数组。 “就在开始之前”没有任何特殊状态或规定。

可以编写这样的循环;您只需要在递减之前进行测试:

for (Thing* thing = thingsTop; thing > thingsBottom; ) {
    thing--;
    doSomething(*thing);
}

答案 1 :(得分:3)

鉴于两个指针都指向同一个数组-只有这样-可以将它们相互比较是安全的。但是,如果您在数组之下下放置1个项目,那么您将超出范围,这是未定义的行为,即使您不访问该项目。

为允许这样的代码,C有一条特殊的规则,该规则允许您将指针指向项目 beyond (超出数组),这是安全的,只要您不取消引用即可该指针指向1以外的地方。

这意味着您必须编写一个递增计数循环,而不是递减计数循环。一个相当典型的例子是:

thing* begin = thing_array;
thing* end   = thing_array + size; // point 1 past the last valid item

for(thing* i = begin; i != end; i++)
{
   do_stuff(i);
}

例如,这几乎就是C ++容器类::iterator的工作方式。

如果您确实需要从头到尾进行迭代,则建议使用整数迭代器:

for(size_t i=0; i<size; i++)
{
  do_stuff(thing_array[size-i-1]);
}