【问题标题】:Iterator, loop causing seg fault! Why is it looping too much?迭代器,循环导致段错误!为什么循环太多?
【发布时间】:2014-04-15 07:08:43
【问题描述】:

下面的代码循环的次数太多了,我很困惑为什么。我环顾四周,并没有看到一个完全像这样的案例。我对迭代器相当陌生,所以这里可能有一些简单的东西。感谢您的帮助!希望对此的回应能在未来帮助其他人。

std::multimap<std::string,std::vector<Token> >::iterator end = theFacts.returnContents().end();
for (mapITER = theFacts.returnContents().begin() ; mapITER != end; mapITER++) {

  cout << "ANOTHER ITERATION THROUGH FACTS" << endl;
  cout << mapITER->first << endl;
  cout << contents.begin()->first << endl;

  if (mapITER->first == contents.begin()->first) {

    cout << "same scheem type so I keep going!" << endl;

    bool successfull = true;

    cout << "starting to seek match --> size --> " << mapITER->second.size() << endl;

    for (int x = 0; x< mapITER->second.size(); x++) {

      std::cout << "processing! "
                << mapITER->second[x].getTokensValue() << "<<<<<<is equal?>>>>>>"
                << contents.begin()->second[x].getTokensValue() << std::endl;

      if (mapITER->second[x].getTokensValue()
        == contents.begin()->second[x].getTokensValue()) {

        cout << "pushing value" << endl;
        newBaby.push_back(contents.begin()->second[x]);

      } else {

        cout << "failure" << endl;
        successfull = false;
      }
    }

    if (successfull) {

      std::cout << "match successfully found" << std::endl;

      if (returnme.contents.empty()) {

        returnme = Relation(contents.begin()->first, newBaby);
        cout << returnme.toString() << endl;

      } else {

        returnme.relationInsert(contents.begin()->first, newBaby);
        cout << returnme.toString() << endl;
      }

    } else {
      // Anser is NO
    }
  }
}

我知道我没有提供完整的代码,但是正如您从以下输出中看到的那样,我正在迭代的地图的大小是 2,那么为什么它会第三次循环!

WHERE TO END --> size of maps (number of iterations that shoudl occure2
ANOTHER ITERATION THROUGH FACTS
snap
snap
same scheem type so I keep going!
starting to seek match --> size --> 4
processing! '12345'<<<<<<is equal?>>>>>>'67890'
failure
processing! 'Snoopy'<<<<<<is equal?>>>>>>'Van Pelt'
failure
processing! '12 Apple'<<<<<<is equal?>>>>>>'34 Pear'
failure
processing! '555-1234'<<<<<<is equal?>>>>>>'555-5678'
failure
ANOTHER ITERATION THROUGH FACTS
snap
snap
same scheem type so I keep going!
starting to seek match --> size --> 4
processing! '67890'<<<<<<is equal?>>>>>>'67890'
pushing value
processing! 'Van Pelt'<<<<<<is equal?>>>>>>'Van Pelt'
pushing value
processing! '34 Pear'<<<<<<is equal?>>>>>>'34 Pear'
pushing value
processing! '555-5678'<<<<<<is equal?>>>>>>'555-5678'
pushing value
match successfully found
PRINT RELATION CALLED 
snap('67890','Van Pelt','34 Pear','555-5678')
ANOTHER ITERATION THROUGH FACTS
Segmentation fault (core dumped)

这是返回内容的作用。

std::multimap<std::string,std::vector<Token> > Relation :: returnContents()
{
    return contents;
}

其中内容是 Relation 类中的私有变量。在我看来,这应该不会导致错误,除非有明显的我不知道。

【问题讨论】:

  • 如果您展示了足够的代码来诊断问题会有所帮助,例如 end 声明在哪里以及它的价值是什么?
  • end 中的mapITER != end 是什么?
  • 在您的情况下尝试 mapITER != theFacts.end()。使用迭代器进行预增量会更好(您不需要复制对象)
  • 猜测:theFacts.returnContents() 不返回引用。
  • 我添加了 end 的实例化。当它通过循环额外(在本例中为第 3 次)并尝试拉 mapITER->first 时,它似乎出现了段错误。我不明白为什么它会第三次循环!

标签: c++ loops iterator segmentation-fault


【解决方案1】:

这是返回内容的作用。

你有你的错误。函数returnContents 返回地图的副本。然后,您从它的两个不同副本上调用 beginend

要么返回一个 (const) 引用:

const std::multimap<std::string,std::vector<Token> >& Relation::returnContents() {
    return contents;
}

或创建本地副本:

std::multimap<std::string,std::vector<Token> > tmp = theFacts.returnContents();
for (mapITER = tmp.begin() ; mapITER != tmp.end(); mapITER++) { ...

【讨论】:

  • 绝对是这样。非常感谢!如果最终制作副本。虽然我想知道,如果我要发送一个 const 引用并对内容进行操作,这些更改会在原始对象上进行吗? (这和传递指针一样吗?)
  • 如果使用 const 引用,则不能更改内容。您将需要一个非常量引用/指针。但我不会在迭代地图时对其进行更改。
猜你喜欢
  • 2017-05-02
  • 2018-12-18
  • 2014-10-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-09
  • 2021-09-07
相关资源
最近更新 更多