程序运行时出现C ++ STATUS_ACCESS_VIOLATION错误

时间:2012-03-20 22:47:48

标签: c++ windows

每次我运行程序时,会弹出这个神秘的错误,说我有某种类型的状态访问冲突。我试过谷歌搜索它所有它想到的是我可能试图访问一些不允许的内存。非常感谢帮助!

运行程序时出现错误:

      2 [main] a 5772 exception::handle: Exception: STATUS_ACCESS_VIOLATION
   1532 [main] a 5772 open_stackdumpfile: Dumping stack trace to a.exe.stackdump

这是.cpp代码:

int main()
{
   Stack s;  //variable declarations
   StackItem *newItem;
   char token, nextChar, prevChar, response, check;
   int lineCount, apostCount;
   char filename[50];
   bool insideComment = false, insideString = false, error, isMatch, delimError = false;
   fstream sourceFile;

   do  //do while response is 'y'
   {
      do //do while opening the source file fails
      {
         cout << "Enter filename of source file: ";
         cin.getline (filename,51);
         sourceFile.open(filename);  //opens the file with given filename
         if (sourceFile.fail())
            cout << "File could not be opened" << endl;  //error if can't open
         sourceFile.clear();
      } 
      while (sourceFile.fail());  //exits if source file doesn't fail

      sourceFile.clear();
      lineCount = 0;  //initializes line count to zero

      while (!sourceFile.eof())  //exits if end of source file is reached
      {
         sourceFile.get(nextChar);  //gets the next character in file

            if ((int)nextChar == '\n')  //if next character is an end line
            {
               lineCount++;  //increments line count
               cout << "Line count: " << lineCount << endl;  //echoes line count
            }

            else if (nextChar == '{' || nextChar == '[' || nextChar == '(')
            {  //continues if next char is an opening token
               newItem->token = nextChar;  //sets newItem's token
               newItem->lineNumber = lineCount;  //sets newItem's line count
               if (!s.isFull())  //continues if stack isn't full
                  s.push(newItem);  //pushes newItem onto the stack
               s.displayStack();  //displays the stack
            }

            else if (nextChar == '}' || nextChar == ']' || nextChar == ')')
            {  //continues if next char is a closing token
               if (!s.isEmpty())  //continues if stack isn't empty
               {
                  isMatch = s.matchStack(nextChar);  //checks if token matches top

                  if (isMatch == true)  //if true, pops the top of the stack
                     s.pop();

                  else  //continues if match is false
                  {
                     newItem->token = nextChar;  //sets newItem's token
                     newItem->lineNumber = lineCount;  //sets newITem's line count
                     s.trailingItem(newItem);  //calls the trailingItem function
                     cout << endl << endl << "Process another file? (y/n): ";
                     cin >> response;  //asks user whether to continue

                     while (response != 'y' && response != 'n')  //checks for input error
                     {
                        cout << "Error! Must enter either y for yes or n for no." << endl;
                        cout << endl << endl << "Process another file? (y/n): ";
                        cin >> response;
                     }
                     break;  //leaves the while loop
                  }
               }

               else if (s.isEmpty())  //continues if stack is empty
               {
                  newItem->token = nextChar;  //sets newItem's token
                  newItem->lineNumber = lineCount;  //sets newItem's line count
                  s.push(newItem);  //pushes newItem onto the top of the stack
                  s.processStack();  //processes the error
                  cout << endl << endl << "Process another file? (y/n): ";
                  cin >> response;  //asks user whether to continue

                  while (response != 'y' && response != 'n')  //checks for input error
                  {
                     cout << "Error! Must enter either y for yes or n for no." << endl;
                     cout << endl << endl << "Process another file? (y/n): ";
                     cin >> response;  //gets user input
                  }

                  break;  //leaves the while loop
               }

               s.displayStack();  //displays the items on the stack
            }

            else if (nextChar == '/')  //continues if next char is a '/'
            {
               sourceFile.get(nextChar);  //gets the next character in file

               if (nextChar == '*')  //continues if next char is a '*'
               {  //at this point a comment has started because of '/' then '*'
                  insideComment = true;  //sets bool to true
                  newItem->token = 'c';  //sets newItem's token to c for "comment"
                  newItem->lineNumber = lineCount;  //sets newItem's line count
                  s.push(newItem);  //pushes the item onto the stack

                  while (insideComment == true && !sourceFile.eof())
                  {  //continues while inside a comment and end of file isn't reached
                     sourceFile.get(nextChar);  //gets the next character in file

                     if (nextChar == '*')  //continues if next char is *
                     {
                        sourceFile.get(nextChar);  //gets the next character in file

                        if (nextChar == '/')  //continues if next char is '/'
                        {  //at this point the comment has ended because of '*' then '/'
                           insideComment = false;  //sets bool to false
                           s.pop();  //pops off the c in the stack
                        }
                     }
                  }
               }

               else if (nextChar == '/')  //continues if next char is a '/'
               {  //at this point a comment has started because of / then another '/'
                  insideComment = true;  //sets bool to true

                  while (insideComment == true && !sourceFile.eof())
                  {  //continues while inside a comment and not at end of file
                     sourceFile.get(nextChar);  //gets the next character in file

                     if (nextChar == '\n')  //leaves comment if next line is entered
                        insideComment = false;  //sets bool to false
                  }
               }
            }

            else if (nextChar == '\n')  //continues if next char is an end line
            {
               lineCount++; //increments line count
               cout << "Line count: " << lineCount << endl;  //echoes line count
            }

            else if (nextChar == '\"' && insideComment == false)
            {  //continues if next char is a " and is not currently inside a comment
               insideString = true;  //sets bool to true b/c " starts a string

               while (insideString == true && !sourceFile.eof())
               {
                  sourceFile.get(nextChar);  //gets the next character in file

                  if (nextChar == '\"')
                     insideString = false;

                  else if (nextChar == '\n')
                  {
                     lineCount++;  //increments line count
                     cout << "Line count: " << lineCount << endl;  //echoes line count
                  }
               }
            }

            else if (nextChar == '\'' && insideComment == false && insideString == false)
            {  //continues if next char is a ' and not in a comment or string
               apostCount = 1; //initializes apostrophe count (chars after first apostrophe)

               while (nextChar != '\'' && !sourceFile.eof())
               {  //continues while next char isn't another ' and not end of file
                  sourceFile.get(nextChar);  //gets the next character in file
                  prevChar = nextChar;
                  apostCount++;  //increments apostrophe count


                  if (nextChar == '\'' && prevChar == '\\' && apostCount <= 3)    
                     nextChar = ' ';  //sets next char to space if 3 or more apostrophes

                  else if (nextChar == '\n')  //continues if next char is an end line
                  {
                     lineCount++;  //increments line count
                     cout << "Line count: " << lineCount << endl;  //echoes line count
                  }
               }

               if (apostCount >= 4)  //if more than 3 chars come after apostrophe
               {  //displays delimeter error
                     cout << "Character delimeter error on line " << lineCount << endl;
                     delimError = true;
               }

               if (delimError == true) //continues if delimiter error occured
                  break;  //leaves 2nd while loop
            }
      }  //end of while loop

      if (s.isEmpty() == true)  //continues if no errors within stack
      {  //displays successful nesting structure to user
         cout << "Source file of " << lineCount << " lines has proper nesting structure";
         cout << endl << endl << "Process another file? (y/n): ";  //asks to continue
         cin >> response;  //gets user's response

         while (response != 'y' && response != 'n')  //checks for input error
            {
               cout << "Error! Must enter either y for yes or n for no." << endl;
               cout << endl << endl << "Process another file? (y/n): ";
               cin >> response;  //gets user input
            }
      }

      else  //continues if errors are present
      {
         s.processStack();  //processes and displays the delimiter errors
         cout << endl << endl << "Process another file? (y/n): ";  //asks to continue
         cin >> response;  //gets user's response

         while (response != 'y' && response != 'n')  //checks for input error
         {
            cout << "Error! Must enter either y for yes or n for no." << endl;
            cout << endl << endl << "Process another file? (y/n): ";
            cin >> response;  //gets user input
         }
      }
   } 
   while (response == 'y');  //opens another file if user entered y for yes
   return 0;  //quits program
}

这是.h代码:

struct StackItem  //defines StackItem structure
{
   char token;  //holds delimeter
   int lineNumber;  //holds the line number of the delimeter in the source file
   StackItem *next;  //points to the next structure
};

typedef StackItem* nodePtr;
const int MAX_ITEMS = 99;

class Stack  //Stack class definition
{
   private:

      nodePtr top;  //points to the top of the stack
      int numberItems;  //number of items in the stack

   public:

      Stack()  //initializes private variables
      { top = NULL; numberItems = 0; }

      ~Stack()
      { while (numberItems > 0)
       { pop();
       }     
      }

      bool isEmpty()  //returns whether the stack is empty or not
      { return top == NULL; }

      bool isFull()  //returns whether the stack is full or not
      { return MAX_ITEMS == numberItems;}

      void push(nodePtr newItem)  //pushes a new item onto the top of the stack
      {
         newItem->next = top;
         top = newItem;
         numberItems++;
      }

      void pop()  //removes the item on top of the stack
      {
         nodePtr p = top;  //sets pointer p to what top points to
         top = top->next;  //top is set to the next struct in stack
         delete p;  //deletes the top item in the stack
         numberItems--;
      }

      void displayStack()  //displays all of the items on the stack
      {
         nodePtr p = top;  //sets pointer p to what top points to
         cout << "Stack Contents: " << endl;
         while(p != NULL)  //while loop to display the stack contents
         {
            cout << p->token << " on line " << p->lineNumber << "." << endl;
            p = p->next;
         }
      }

      void processStack()  //displays the error for each delimeter in stack
      {
         nodePtr p = top;  //sets pointer p to what top points to
         while (p != NULL)  //continues until p points to NULL
         {
            cout << "\" " << p->token << " \" on line " << setw(5) << right;
            cout << p->lineNumber << " has no matching element" << endl;
            p = p->next;
         }
      }
      //determines whether the stack delimeter matches the current character
      bool matchStack(char character)  
      {
         bool match = false;
         if (top->token == '{')
         {
            if (character == '}')
               match = true;  //sets bool to true if we have { and }
         }
         else if (top->token == '[')
         {
            if (character == ']')
               match = true;  //sets bool to true if we have [ and ]
         }
         else if (top->token == '(')
         {
            if (character ==  ')')
               match = true;  //sets bool to true if we have ( and )
         }
         return match;  //returns the bool
      }
      //called if we have a trailing item that doesn't match stack delimeter
      void trailingItem(nodePtr newItem) //displays what doesn't match
      {
         cout << "\" " << top->token << " \" on line " << setw(5) << right;
         cout << top->lineNumber << " doesn't match \" " << newItem->token;
         cout << " \" on line " << setw(5) << right << newItem->lineNumber;
      }
};

这是a.exe.stackdump文件:

Exception: STATUS_ACCESS_VIOLATION at eip=00401701
eax=61100049 ebx=0028CD40 ecx=00A01998 edx=00000000
esi=0028CD40 edi=00000000 ebp=0028CD18 esp=0028CAF0
program=C:\Users\Tyler\Desktop\Program 2\a.exe, pid 5772, thread main
cs=0023 ds=002B es=002B fs=0053 gs=002B ss=002B
Stack trace:
  Frame Function Args
  0028CD18 00401701 (00000001, 009E8628, 009E8510, 00000001)
  0028CD68 61007038 (00000000, 0028CDA4, 61006980, 7EFDE000)
End of stack trace

2 个答案:

答案 0 :(得分:4)

您声明StackItem *newItem;这是一个指针,但您永远不会将其初始化为任何内容,因此其内容未定义。 然后,只要你执行newItem->...程序就会崩溃,因为它没有指向任何有效的内存。

解决方案是在这里和那里添加一些newItem = new StackItem以创建实际对象。很自然地,StackItem类的构造函数(或几个)是最受欢迎的。

答案 1 :(得分:4)

您尚未初始化newItem指针,但正在取消引用它。

另外,您告诉cin.getline 50字节字符是51字节宽。

我偶然发现了两个问题。