2012-03-20 3 views
3

프로그램을 실행할 때마다 몇 가지 유형의 상태 액세스 위반이 있음을 알리는이 신비한 오류가 발생합니다. 내가 인터넷 검색을 시도하고 그것으로 온다는 내가 허용되지 않는 일부 메모리에 액세스하려고 수도 있습니다. 도움을 주시면 감사하겠습니다! 여기프로그램을 실행할 때 C++ STATUS_ACCESS_VIOLATION 오류가 발생합니다.

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

: 여기

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 코드 : 여기
 2 [main] a 5772 exception::handle: Exception: STATUS_ACCESS_VIOLATION 
    1532 [main] a 5772 open_stackdumpfile: Dumping stack trace to a.exe.stackdump 

가 .CPP 코드 : 나는이 프로그램을 실행하면 다음

오류입니다 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

'a.exe.stackdump'파일에는 문제를 식별하는 데 도움이되는 중요한 정보가 들어 있습니다. –

+2

왜 디버거에서 코드를 실행하지 않으시겠습니까? –

+1

문제가 발생하는 가장 간단한 방법으로 프로그램을 단순화하고 디버거 (또는 printf)를 사용하여 문제가 발생한 위치를 파악하십시오. –

답변

3

포인터 인 StackItem *newItem;을 선언했지만 내용을 정의하지 않으므로 아무 것도 초기화하지 않습니다. 그러면 가능한 한 빨리 newItem->... 프로그램이 유효한 메모리를 가리 키지 않으므로 프로그램이 중단됩니다.

해결책은 실제 개체를 만들기 위해 여기 저기에 몇 가지 newItem = new StackItem을 추가하는 행을 따릅니다. 그리고 당연히 StackItem 클래스의 생성자 (또는 몇 개)가 가장 환영받을 것입니다.

+0

감사합니다! 지금 실제로 실행 중입니다 :) –

3

newItem 포인터를 초기화하지 않았지만 역 참조합니다.

또한 cin.getline에 50 바이트 문자의 길이가 51 바이트라고 말했습니다.

캐주얼 한 눈빛에서 나는 단지 두 가지 문제점을 발견했습니다.

관련 문제