【问题标题】:string iterator is not dereferencable字符串迭代器不可取消引用
【发布时间】:2016-10-07 18:06:47
【问题描述】:

我正在使用一个库来解析 .pgn 文件,当我尝试运行该项目时,我发现了这个错误:Debug Assertion Failed!程序:C:\windows\SYSTEM32\MSVCP110D.dll 文件:c:\program files (x86)\microsoft visual studio 11.0\vc\include\xstring 线路:79 表达式:字符串迭代器不可取消引用 有关您的程序如何导致断言失败的信息,请参阅关于断言的可视 C++ 文档。

问题是当迭代器到达文件末尾时,它没有指向任何东西(start iterator (itr1) == end iterator (itr2)),我尝试添加条件来检查itr1是否到达末尾的文件,但它是无用的。 所以请告诉我我的错在哪里。 这是我的代码 source.cpp 文件:

#include <iostream>
#include <fstream>
#include <PGNGameCollection.h>
int main()
{
    std::ifstream pgnfile("sample.pgn");
    pgn::GameCollection games;
    pgnfile >> games;
    std::cout << "the file sample.pgn contains " << games.size() << "games"     << std::endl;
    system("pause");
    return 0;
}

这是导致错误的类函数:

bool pgn::Parser::getComment(std::string::const_iterator &itr1, const std::string::const_iterator &itr2, pgn::CommentText &out)
{
    std::string::const_iterator local_itr=itr1;
    std::string comment;
    if(*local_itr != '{')
        return false;
    local_itr++; //skipping '{'

    while((*local_itr != '}') && (local_itr != itr2))
    {
        comment += *local_itr++;
    }
    local_itr++; //skipping '}'
    skipBlanks(local_itr, itr2);
    itr1=local_itr;
    out=pgn::CommentText(comment);
    return true;
}

skipBlanks 函数:

void pgn::Parser::skipBlanks(std::string::const_iterator &itr1, cost std::string::const_iterator &end)
{
    while((itr1 != end) && (isspace(*itr1)))
    {
        itr1++;
    }
}

我已经在 stackoverflow 和 google 搜索了所有类似的问题,但我找不到答案。我也逐行跟踪代码,直到找到导致错误的函数。

【问题讨论】:

  • 调试器是解决此类问题的正确工具。 询问 Stack Overflow 之前,您应该逐行逐行检查您的代码。如需更多帮助,请阅读How to debug small programs (by Eric Lippert)。至少,您应该 [编辑] 您的问题,以包含一个重现您的问题的 Minimal, Complete, and Verifiable 示例,以及您在调试器中所做的观察。
  • 在这里提问之前我已经逐行调试了代码,但是找不到答案!
  • 那你可能用错了调试器。
  • 使用调试器帮助我找到了导致错误的函数,但我无法修复它。我正在使用一个不是我编写的库,我尝试对其进行编辑以解决错误,但我不能。

标签: c++ visual-studio-2012


【解决方案1】:

如果itr2 是您的结束迭代器,那么您必须在尝试取消引用之前检查迭代器的结束条件

while((local_itr != itr2) && (*local_itr != '}'))

你这样做是反过来的,这肯定会导致你描述的问题。

在函数的最开始添加对结束条件的检查也可能有意义,因为您还取消了对 local_itr 的引用。

此外,如果您的循环因local_itr 到达itr2 而终止,而itr2 及其后没有任何内容,则循环后的代码毫无意义。在这种情况下,您不能增加 local_itr

【讨论】:

  • 我试过了,但同样的错误信息出现在 Expression: string iterator not incremental
  • @Norhan Foda:嗯……也一样?怎么一样?您将原始错误引用为“字符串迭代器是 not dereferencable”,现在您得到“not incrementable”。 “不可递增”是一个完全不同的错误,它来自您在循环后尝试执行local_itr++。如果您到达终点,后者将毫无意义。这是一个不同的问题,需要单独修复。如果它已经到达末尾,请不要尝试增加迭代器或从中读取任何内容。
  • 我检查了迭代器是否像这样到达末尾: if(itr1 != itr2){local_itr++;} 所以 local_itr 只有在它不是文件末尾时才会增加。这让我回到了不可取消引用的字符串迭代器。
  • @Norhan Foda:是的,它可能会“带你回去”,但会去一个不同的地方,你没有向我们展示。您的代码中可能仍有很多地方忘记检查结束条件 尝试取消引用迭代器,即与原始代码中的错误相同。 (例如,skipBlanks 内部发生了什么?)。您必须找到所有此类错误并一一修复。
  • 相信我,我试图检查代码中的所有地方,如果有一种方法可以让我上传整个文件以便您检查它,请告诉我该怎么做。
猜你喜欢
  • 1970-01-01
  • 2012-10-30
  • 2017-11-26
  • 2015-12-11
  • 2015-01-13
  • 1970-01-01
  • 2014-04-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多