分段错误的原因?

时间:2013-11-14 23:51:13

标签: c++ segmentation-fault gdb lexical-analysis debug-backtrace

我在C ++中为扫描程序编写了一些代码,但我一直收到分段错误。奇怪的是,分段错误发生在代码完成时。我认为这与我的扫描功能和在其中使用file.get()有关,但这不会导致代码的那一行出现分段错误吗?我有一个简单的main.cpp,它在执行cout语句时调用函数,并且在return语句之后发生分段错误。当我运行GDB并回溯时,我收到了:

  

编程接收信号SIGSEGV,分段故障       __do_global_dtors_aux()中的0x00011260       (GDB)
      (gdb)回溯
      __do_global_dtors_aux()中的#0 0x00011260       _fini()中的#1 0x00012504       来自/lib/libc.so.1的_exithandle()中的#2 0xfefc3120
      来自/lib/libc.so.1的exit()中的#3 0xfefb10e0       #start()

中的#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.cc中的一些其他功能:

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

2 个答案:

答案 0 :(得分:1)

我弄清楚导致我的分段错误的原因。我需要为我的结构malloc空间。我把它添加到我的代码中:

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

答案 1 :(得分:-1)

尝试在存在函数之前关闭文件流。

file.close();