2010-01-22 52 views
2

我在C++编程语言阅读:特别版不使用迭代器已调整大小的矢量

Don't use iterators into a resized vector

考虑这个例子。

vector<int>::iterator it = foo.begin(); 

while (it != foo.end()) { 
    if (// something) { 
    foo.push_back(// some num); 
    } 
    ++it; 
} 

这有问题吗?在矢量调整大小之后,循环条件中的foo.end()会向前推1吗?

P.S.另外,如果向量为x个整数预留了空间,该怎么办?如果push_back没有违反这个空间,它会不会是一个问题(我会假设如果it.end()指向一个超过vector中包含某个元素的最后一个元素)。

回答

5

是的,它有问题。

push_back的任何调用都有可能使所有迭代器失效为一个向量。

foo.end()将始终检索有效的结束迭代器(它可能与上次返回的值foo.end()不同),但it可能已失效。这意味着递增或比较它可能会导致未定义的行为。

+0

如果矢量的大小适合10个整数,该怎么办?假设push_back没有超过这个预分配的大小,它是否仍然使迭代器无效? – Anonymous 2010-01-22 20:42:22

+0

@Person:严格地说,如果'push_back'不会导致向量的size()超出之前在调用reserve时给出的请求容量,那么你可以保证对'push_back'的调用不会导致重新分配并且不会使迭代器失效到对象。不过,你仍然需要调用'end()'来获得正确的'end()'。 – 2010-01-22 20:45:09

+0

谢谢。我认为最好不要用预留空间和迭代器跳舞,而应该在这种情况下使用数组索引。 – Anonymous 2010-01-22 20:47:52

1

是的,存在问题。无论foo.end()it可能会被push_back()无效。编辑:(即它不是只是,结束可能会改变;有可能整个向量的缓冲区可能被重新分配,所以迭代器全部变得无效)。

1

是的,这有一个问题。 push_back会使您调用的矢量的任何迭代器失效。因此在拨打push_back后,执行++it甚至不合法。这是一个未定义的行为,所以它有时可能会起作用,有时可能会失败,但不应该依赖它的工作。

0

正如其他人所说,push_back()可能会使向量的所有迭代器无效。其原因是矢量中的数据存储在连续内存区域中。如果push_back()或任何其他调整向量大小的操作都会导致向量的大小超出分配区域的容量,该区域将被重新分配并最终放在内存中的不同位置,而所有迭代器仍然会引用旧的内存区域。