什么可能导致调试断言错误。具体来说,在我的代码中

时间:2011-07-12 18:23:31

标签: c++ debugging

我正在为学校项目编写编译器,这项任务要求我将文本文件的标记打印到控制台窗口。我想说清楚希望我的功课完成。

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

  

Debug Assertion使Final.exe失败   文件:f:\ dd \ vctools \ crt_bld \ self_x86 \ crt \ src \ isctype.c表达式:   (无符号)(c + 1)< = 256

我已经包含了我的函数及其相关的头文件。除了函数调用之外,main中没有任何内容。如果可能的话,你能看到我没看到的东西。我意识到我的代码结构很差,我不会说谎(毕竟我在学校)。所以,任何评论,批评和建议都是非常受欢迎的。永远,谢谢你的任何时候。

.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 

4 个答案:

答案 0 :(得分:2)

调试断言错误源于对std::isalpha/isdigit的调用,当您向其传递值为&gt;的参数时255,这是类型char(您可能应该使用而不是int)的最大值,可以容纳。我不能告诉你确切的起源,因为你没有提供源文件,但你应该能够很容易地自己弄明白:在调试器下运行程序,它会在断言处中断。向上移动调用堆栈并检查变量的值,这应该给你一个线索。

一些提示:

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

答案 1 :(得分:1)

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

// 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;  
       }
   }
}

答案 2 :(得分:1)

你忘记了

#include <cctype>

为了使用isdigit()和isalpha()

和这个

c = letters[pos++];

看起来像是一个bug的来源。 pos总是递增,但是它会不会停止?如果它到达最后一个字符(letters.length() - 1)并且你点击这一行会发生什么:增量?我怀疑阵列超出界限。

答案 3 :(得分:0)

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

您最常看到的错误可能来自

token = token + letters; 

字母不是以null结尾的(string :: copy不提供空终止,并且你不会为null保留空格),因此+运算符会掉线并遇到令人讨厌的东西。< / p>

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