【问题标题】:What can cause a Debug Assertion Error. Specifically, in my code什么可能导致调试断言错误。具体来说,在我的代码中
【发布时间】:2011-10-03 21:22:00
【问题描述】:

我正在为一个学校项目编写一个编译器,这个任务要求我将一个文本文件的标记打印到控制台窗口。我想明确表示我希望为我完成作业。

我一直在使用这个愚蠢的函数,它遍历文件,并将一个 char 或一个 c 字符串值(我的导师在他的这部分说明上含糊不清......)连接到一个名为“token. "我可以很好地完成文件的第一行,即“main()”,但是当我尝试访问下一行时,我得到了两个错误之一。第一个是字符串下标超出范围错误,尽管我认为这是因为我试图访问不存在的字符串数组的一部分。我遇到的最普遍错误是调试断言错误:

调试断言失败 Final.exe 文件:f:\dd\vctools\crt_bld\self_x86\crt\src\isctype.c 表达式: (无符号)(c+1)

我已经包含了我的函数及其相关的头文件。除了函数调用之外,main 中什么都没有发生。如果可能的话,你能看到我看不到的东西吗?我意识到我的代码结构很差,我不会撒谎(毕竟我在学校)。因此,非常欢迎任何 cmets、批评和建议。永远,谢谢你。

.CPP 文件(现在的样子)

    #include <iostream> 
    #include <string>

    using namespace std; 

    void tokenWork::openFile()
    {
        fileName = "test.txt"; 

        source.open(fileName);

        if(!source.is_open())
        {
       cout << "Cannot find file " << endl; 
        }
    }

    void tokenWork::traveseLine()
    {

    pos = 0; 
    while (!source.eof())
    {  
          getline(source,myLine); 
          int length = myLine.length(); 
          letters = new char[length];
          myLine.copy(letters,length); 

          c = letters[pos]; 

          if (isalpha(c))
             token = token + myLine[pos]; 
          else if (isdigit(c))
             token = token + letters; 
          else 
          {
             cout << token << endl; 
             token = ""; 
          }

          if (c == '{' || c == '}' || c == '+' || c == '=' || myLine[pos] == '(' || c == ')' || c == ';')
                cout << myLine[pos] << endl;  
          c = letters[pos++]; 
    }
}

.h 文件

    #ifndef H_LEX
    #define H_LEX

    #include <string> 
    #include <iostream> 
    #include <fstream> 

    using namespace std; 

    class tokenWork
    {
    public: 
    std::string fileName; 
    std::string myLine; 
    std::string token; 

    int pos; 
    int length; 
    int c;

    char *letters; 

    ifstream source; 

    void openFile(); 
    void traveseLine(); 
    void closeFile(); 

};

    #endif 

【问题讨论】:

  • 我的建议是学习使用调试器。在您的函数中设置断点并通过它进行调试,以查看导致错误的确切原因。
  • 这条线在做什么? if (c == '{' || c == '}' || c == '+' || c == '=' || myLine[pos] == '(' || c == ') ' || c == ';').
  • 你能提供你的两行输入吗?
  • 请忽略此帖。感谢所有看过它的人!

标签: c++ debugging


【解决方案1】:

该调试断言错误源于对std::isalpha/isdigit 的调用,当您将一个值> 255 的参数传递给它时,这是char 类型的最大值(您可能应该在这里使用它而不是int ) 能把持住。尽管您没有提供源文件,但我无法告诉您确切的来源,但是您应该能够很容易地自己弄清楚:在调试器下运行程序,它会在断言处中断。在调用堆栈中向上移动并检查变量的值,这应该会给你一个线索。

几个提示:

  • 您在这里使用的是 c++,不需要使用原始字符数组。请改用 std::string。
  • 不要使用命名空间标准;在头文件中:包含该文件的所有内容都将导入整个 std 命名空间
  • 如果包含在标头中,则不必在源文件中再次包含它
  • 学习使用调试器,它是一种非常宝贵的工具,可以帮助您了解出现问题的原因

【讨论】:

    【解决方案2】:

    如果您只想在每个给定的行上打印标记,我对您所做的所有额外工作感到非常困惑。缩小你的功能(和一个小的改变)应该让你开始:

    // note, poorly named function, it traverses the whole file
    void tokenWork::traveseLine()
    {
    
    pos = 0; 
    while (!source.eof())
    {  
       getline(source,myLine); 
    
       int len = myLine.size();
    
       // NOTE: This was missing from your code, it traverses the line
       //       that was read in with getline() above.
       for(int x = 0; x < len; ++x)
       {
           // NOTE: This is (in my opinion) a slightly more readable
           //       version of your if() statement above on tokens
           //       It doesn't have all your tokens, additional ones
           //       can be added by adding a case for them above the 
           //       line that prints them out.  Since there is no break
           //       statement, the functionality for all the cases above 
           //       fall through so they all get printed out.
           switch(myLine[x])
           {
              case '{':
              case '}':
              case '+':
              case '=':
              // add additional tokens as case statements as necessary
                cout << myLine[x] << endl;  // print it out
                break;
              default:   // not a token
                break;  
           }
       }
    }
    

    【讨论】:

    • 这看起来不错,但请使用 size_t 来存储 myLine.size() (编译器会抱怨 64 位平台,这是有原因的)或者更好的是 const size_t
    • 确实如此——目标是让 OP 达到舒适的水平,并且不想通过太多类型(可能还没有看到)来处理它们。注意如果len改为size_t,for循环中的x也应该是这样。
    【解决方案3】:

    你忘了

    #include <cctype>
    

    为了使用 isdigit() 和 isalpha()

    还有这个

    c = letters[pos++];
    

    看起来像是错误的来源。 pos 总是递增,但它会停止吗?如果它到达最后一个字符(letters.length()-1)并且你点击了这一行会发生什么:增量?我怀疑数组超出范围。

    【讨论】:

      【解决方案4】:

      很难指出代码中的特定位置 - 它有很多问题......

      你看到的错误很可能是由

      引起的
      token = token + letters; 
      

      letters 不是以 null 结尾的(string::copy 不提供以 null 结尾的功能,而且无论如何您也不会为 null 保留空间),因此 + 运算符会落到最后并遇到一些讨厌的事情。

      除此之外,您似乎在每个 getline 增加一次 pos 并且从不重置它。您的代码看起来应该有一个内部循环,但我没有看到任何内容。

      【讨论】:

        猜你喜欢
        • 2012-01-15
        • 1970-01-01
        • 2023-03-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-09-22
        • 2011-10-30
        • 2018-02-16
        相关资源
        最近更新 更多