2013-11-14 98 views
-2

我已經在C++中爲掃描器編寫了一些代碼,但是我一直在收到分段錯誤。奇怪的是分段錯誤發生在代碼完成時。我認爲它與我的掃描功能和file.get()在它的使用有關,但不會導致在該行代碼段出現分段錯誤?我有一個簡單的main.cpp,它在調用cout語句時調用函數,並且在返回語句之後發生了段錯誤。當我運行GDB和回溯我收到:分段錯誤的原因?

程序接收到的信號SIGSEGV,分段錯誤。
0x00011260在__do_global_dtors_aux()
(GDB)
(GDB)回溯
#0 0x00011260在__do_global_dtors_aux()
#1 0x00012504在_fini()
#2 0xfefc3120在_exithandle()從/ LIB/libc的.so.1
#3 0xfefb10e0在_start從/lib/libc.so.1
#4 0x00011218出口()()

這裏的簡單的main.cpp:

int main(int argc, char *argv[]) { 

    tokenType * token, * testtk; 
    string filename; 



    if(argc == 2){ 
     filename = argv[1]; 
     filename.append(".lan"); 
    } 

    scan(filename); 


    cout << endl; 
    cout << "WHAT?!" << endl; 

return 0; 
} 

而這裏只是掃描儀的功能部分:

void scan(string filename){ 

    char current; 
    char look; 
    int currentline = 1; 
    Type test; 
    tokenType * testtk; 

    std::ifstream file(filename.c_str());  // open file 


    /***scanner creation***/ 
    while (file.good())     // loop while extraction from file file possible 
    { 


     int state = 0; 
     int lookstate = 0; 
     int type = 0; 
     int i = 0; 
     int nextstate;  



     look = file.peek(); 

     /*** check for comments ***/ 
     if(assignType(look)==5){    
     current = file.get();   //"current = look" at this point 
     current = file.get();   //current moves to next character 
      while(current != 24) { 
       current = file.get(); 
      } 
     } 


     initializeToken(testtk); 

     while(state >= 0) { 

      current = file.get();   // get character from file 
      look = file.peek(); 
      lookstate = state; 



      if(assignType(current)!=24){   //keeps newlines from printing 
      testtk->str[i] = current;   //put current scanned char into string 
      } 
      testtk->tokenId = (tokenIdType) state;  
      nextstate = table[state][assignType(current)]; 


      state = nextstate; 

      if(assignType(current)==24) {   //keeps track of '\n' 
       currentline++; 
      } 

      if(i<STRSIZ) i++; 

     } 

     testtk->line=currentline; 

     printToken(testtk); 
    } 

file.close(); 
} 

任何幫助,至於是什麼原因造成這種分段錯誤,將不勝感激,

編輯

這裏最我的token.h:

typedef enum 
    { EOFtk, IDtk, NOTtk, DOTtk, NUMtk, COMMENTtk, ASSIGNtk, EQUALtk, LESSEQtk, 
     GREATEQtk, PLUStk, MINUStk, MULTtk, DIVtk, MODtk, PARENLtk, 
     PARENRtk, COMMAtk, CURLYLtk, CURLYRtk, SEMItk, BRACKLtk, BRACKRtk, COLONtk, 
     LESStk, GREATtk, STARTtk, STOPtk, THENtk, IFtk, IFFtk, WHILEtk, VARtk, INTtk, 
     FLOATtk, DOtk, READtk, WRITEtk, VOIDtk, RETURNtk, DUMMYtk, PROGRAMtk 
    } tokenIdType; 

typedef enum 
    { WS, LETTER, NUMBER, AMBER, NOT, PLUS, MINUS, MULT, DIV, 
     MOD, EQUAL, LESS, GREATER, UNDERSC, DOT, PARENL, 
     PARENR, COMMA, CURLYL, CURLYR, SEMI, BRACKL, BRACKR, COLON, 
     NEWLINE, NONALPHA, EOF 
    } Type;  

typedef struct 
    { char str[STRSIZ]; 
     tokenIdType tokenId; 
     int line; 
    } tokenType; 

,這裏是一些在我scanner.cpp其他功能:

Type assignType(unsigned char current) { 
    Type temp; 

    if((current <= 122 && current >=97) || (current <= 90 && current >=65)){ 
     temp = LETTER; 
     return temp; 
    } 

    if(current <= 57 && current >=48) { 
     temp = NUMBER; 
     return temp; 
    } 

    if(current == 10) { 
     temp = NEWLINE; 
     return temp; 
    } 

    switch (current) { 
     case ' ': 
      temp = WS; 
      break;   
     case '&': 
      temp = AMBER; 
      break;       
     case '!': 
      temp = NOT; 
      break;     
     case '+': 
      temp = PLUS; 
      break; 
     case '-': 
      temp = MINUS; 
      break; 
     case '*': 
      temp = MULT; 
      break;     
     case '/': 
      temp = DIV; 
      break; 
     case '%': 
      temp = MOD; 
      break; 
     case '=': 
      temp = EQUAL; 
      break; 
     case '<': 
      temp = LESS; 
      break;     
     case '>': 
      temp = GREATER; 
      break; 
     case '_': 
      temp = UNDERSC; 
      break; 
     case '.': 
      temp = DOT; 
      break; 
     case '(': 
      temp = PARENL; 
      break;     
     case ')': 
      temp = PARENR; 
      break; 
     case ',': 
      temp = COMMA; 
      break; 
     case '{': 
      temp = CURLYL; 
      break; 
     case '}': 
      temp = CURLYR; 
      break;     
     case ';': 
      temp = SEMI; 
      break;     
     case '[': 
      temp = BRACKL; 
      break; 
     case ']': 
      temp = BRACKR; 
      break;  
     case ':': 
      temp = COLON; 
      break;  
     default : 
      temp = NONALPHA; 
      break;  
    } 

    return temp; 
} 




void initializeToken(tokenType *token){ 

    for(int i=0;i<STRSIZ;i++){ //initialize tokenType str 
    token->str[i]=0; 
    } 

} 

void printToken(tokenType *token){ 

    if(token->tokenId != COMMENTtk && token->tokenId != EOFtk) { //ignore comments 
      cout<<"Line:"; 
     cout.width(3); 
      cout<<token->line; 
     cout.flush(); 
      cout<<" TokenID:"; 
     cout.width(3); 
      cout<<token->tokenId; 
     cout.flush(); 
     cout<<" String: "; 
      printf("%s\n", token->str); 
    } 
} 


bool isToken(int state, int look){ 

    if(table[state][assignType(look)] >=0) 
     return false; 
    else return true; 
} 

bool compareStr(char x[], char y[]){ 
    int score; 
    for(int i=0;i<STRSIZ;i++) { 
     if(x[i] != y[i]) 
      score++; 
     } 
    if(score == 0) 
     return true; 
    else 
     return false; 
} 

回答

1

我想清楚是什麼導致了我的分割錯誤。我需要爲我的結構malloc的空間。我將此添加到我的代碼中:

tokenType * testtk = (tokenType *) malloc(sizeof(*testtk)); 
. 
. 
. 
<existing code> 
. 
. 
. 
free(testtk); 
-1

嘗試現有的功能之前,關閉文件流。

file.close(); 
+0

對不起,原始代碼確實使用了file.close();函數結束之前。我編輯了我的問題來反映(以及添加最後的})。 – Evytyn

+0

你可以顯示tokenType類的聲明和實現嗎?只是構造函數和析構函數會做 –

+0

我已經從我的掃描器中添加了其他函數,並從我的token.h中添加了代碼。再次感謝您提供的任何幫助。 – Evytyn