列表<对象*>迭代器中的分段错误



我正在学习C++,现在我在迭代器方面遇到了问题。这是我的情况:我这里有这个代码。

// std::list<Dragon*> dragons = cave.getDragons();
for (std::list<Dragon*>::iterator it = cave.getDragons().begin(); it != cave.getDragons().end(); it++){
        os << std::endl << (*it)->getName();
}

它返回分段错误。这是我的列表和我的getDragons()方法:

std::list<Dragon*> dragons;
std::list<Dragon*> getDragons() const {return dragons;}

我的问题是...为什么我这样做会有分段错误,但是如果我使用被注释的 dragons 变量,不要?谢谢!

getDragons()按值返回std::list,因此每次调用getDragons()时,都会获得dragons列表的副本。 因此,您的for循环正在比较来自不同临时std::list对象的迭代器,并将尝试取消引用无效的迭代器。

你需要做一些更像这样的事情:

std::list<Dragon*> dragons = cave.getDragons();
for (std::list<Dragon*>::iterator it = dragons.begin(); it != dragons.end(); it++){
    os << std::endl << (*it)->getName();
}

或者,如果您使用的是 C++11 或更高版本,请改用 for-range 循环:

for (Dragon *dragon : cave.getDragons()) {
    os << std::endl << dragon->getName();
}

否则,您需要更改getDragons()以通过引用返回std::list

const std::list<Dragon*>& getDragons() const {return dragons;}

然后,原始for代码将起作用,尽管它仍然会在每次循环迭代中调用getDragons()。 最好缓存对局部变量的单次调用的结果:

const std::list<Dragon*> &dragons = cave.getDragons();
for (std::list<Dragon*>::const_iterator it = dragons.begin(); it != dragons.end(); it++){
    os << std::endl << (*it)->getName();
}

或者,使用上面显示的相同 C++11 for-range循环。

正如 Remy 所解释的那样,您的潜在错误是列表副本的使用(这不仅容易出错,而且效率低下)。因此,正确的治疗方法是永远不要创建这样的副本(Remy 的答案仍然建议这样做)。为此,getDragons()方法应返回引用。

struct Cave
{
  /* ... */
  std::list<const Dragon*> const&getDragons() const;
};

此外,您应该尽可能使用 auto 关键字(当然至少使用 2011 标准)。

for(auto const&dragon : cave.getDragons())
  os << std::endl << dragon.getName();

相关内容

  • 没有找到相关文章