简体   繁体   English

解引用C ++ STL列表迭代器

[英]Dereferencing C++ STL list iterator

I'm looping through two STL lists (L1, L2) like so: 我正在遍历两个STL列表(L1,L2),如下所示:

list<int>::const_iterator itr1 = L1.begin();
list<int>::const_iterator itr2 = L2.begin();

for (itr1; itr1 != L1.end(); itr1++) {
   if (*itr1 < *itr2) {
     //some code
   }

}

It compiles fine but when I run it, it says "Expression: list iterator not dereferencable" 它可以很好地编译,但是当我运行它时,它会显示“表达式:列表迭代器不可引用”

Now in class we made a mock version of the STL list where we wrote our own STL list and we had overloaded the *operator to dereference an iterator. 现在在课堂上,我们制作了STL列表的模拟版本,在其中编写了自己的STL列表,并且使* operator重载以取消对迭代器的引用。 However, obviously it's not working here. 但是,显然它在这里不起作用。

How can I dereference an iterator, or if STL list does it differently, how does it do it. 我如何取消对迭代器的引用,或者如果STL列表使用不同的方式,它将如何进行引用。 I looked through this: 我浏览了一下:

http://www.sgi.com/tech/stl/List.html http://www.sgi.com/tech/stl/List.html

documentation and didn't seem to find anything accept the member "reference" but still did not see how to reference what an iterator is pointing to, unless it's the first or last part of the list. 文档,并且似乎没有找到任何东西接受成员“引用”,但仍然看不到如何引用迭代器指向的内容,除非它是列表的第一部分或最后一部分。

Anyone know what's going on here? 有人知道这是怎么回事吗? Thank you 谢谢

here is a pastebin: 这是一个pastebin:

http://pastebin.com/YRddqjmN http://pastebin.com/YRddqjmN

My guess: 我猜:

L2 is empty, so L2.begin() is the same as L2.end() . L2为空,因此L2.begin()L2.end()相同。

Which means L2.begin() is returning a non-referencable iterator and you are thus invoking undefined behavior. 这意味着L2.begin()返回的是不可引用的迭代器,因此您正在调用未定义的行为。

This (implementation specific) message suggests to me that you dereferenced an invalid iterator. 此(特定于实现的)消息向我建议您取消引用了无效的迭代器。 This has nothing to do with syntax/compile-time semantics so no surprise that your compiler didn't complain. 这与语法/编译时语义无关,因此您的编译器不会抱怨也就不足为奇了。 However note that iterators do have run-time semantics: in this case I'd wager that the code is called with an empty L2 list, so that itr2 == L2.end() . 但是请注意,迭代器确实具有运行时语义:在这种情况下,我押注该代码将使用一个空的L2列表进行调用,以便itr2 == L2.end() That means that *itr2 results in undefined behaviour. 这意味着*itr2导致不确定的行为。 Luckily this seems to trigger an error-message rather than blowup in your face. 幸运的是,这似乎触发了错误消息,而不是使您的脸庞膨胀。

while ( *itr2 < *itr1 ) {
    itr2++;
}

That code has no check for running off the end of L2. 该代码没有检查是否会耗尽L2的末尾。 Maybe add a check for itr2 != L2.end() to that. 也许添加一个检查itr2 != L2.end()

可以取消引用标准列表迭代器,只要它在列表的范围内即可,即[list.begin(),list.end()),而列表不为空。

The other answers are correct that a bad list iterator is being dereferenced because of two bugs. 其他答案是正确的,因为有两个错误,正在取消引用不良列表迭代器。 Looking at your pastebin, 看着你的pastebin,

This condition is backwards: 这种情况是倒退的:

if ( (*itr1 == *itr2) && (itr2 != L2.end()) ) {

It should be 它应该是

if ( (itr2 != L2.end()) && (*itr1 == *itr2) ) {

in order to check that itr2 is valid before using it. 为了在使用itr2之前检查它是否有效。 Also, the first condition 另外,第一个条件

if ( L1.empty() && L2.empty() ) {
            cout << "Returning an empty list because the two arugment lists were empty\n\n";

should be a disjunction: 应该是一个析取:

if ( L1.empty() || L2.empty() ) {
            cout << "Returning an empty list because at least one of the two argument lists was empty\n\n";

but it's not even really necessary. 但这甚至不是必须的。

(Oh, and, are you aware of set_intersection , which is part of the standard library?) (哦,您是否知道set_intersection ,它是标准库的一部分?)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM