Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ STATUS_ACCESS_VIOLATION error when program runs

Tags:

c++

windows

Everytime I run the program, this mysterious error pops up saying that I have some type of status access violation. I have tried googling it and all it comes up with is that I might be trying to access some memory that is not allowed. Help would be highly appreciated!

Here is the error when I run the program:

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

Here is the .cpp code:

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
}

Here is the .h code:

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

Here is the a.exe.stackdump file:

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
like image 877
Tyler Gavin Avatar asked Mar 20 '12 22:03

Tyler Gavin


2 Answers

You declare StackItem *newItem; that is a pointer, but you never initialize it to anything, so its contents are undefined. Then, as soon as you do newItem->... your program will crash, as it is not pointing to any valid memory.

The solution would be along the lines of adding a few newItem = new StackItem here and there to create the actual objects. And naturally a constructor (or several) to the StackItem class would be most welcome.

like image 116
rodrigo Avatar answered Oct 17 '22 10:10

rodrigo


You have not initialized the newItem pointer, but are dereferencing it.

Also, you told cin.getline that a 50 byte character is 51 bytes wide.

Just two problems I spotted at a casual glance.

like image 4
Kaz Avatar answered Oct 17 '22 10:10

Kaz