2013-08-02 34 views
0

我的程序执行得很好,除了最后,当我调试它,它调用我的析构函数后出现分段错误。我不确定问题的原因是什么。我已经发布了2个相关文件。我的析构函数需要在这个函数中做什么?

Breakpoint 1, main() at Prog3.cc:12 

12  cout << "Program executed" << endl; 

(gdb) s 

Program executed 

~Lex (this=0x80375c4) at lex.cc:36 

36  delete [] str; 

(gdb) s 

37  } 

(gdb) s 

Program received signal SIGSEGV, Segmentation fault. 
0xfef49418 in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string() from /usr/sfw/lib/libstdc++.so.6 
(gdb) Quit 

lex.h低于:

#ifndef LEX_H 
#define LEX_H 
#include "token.h" 
#include <iostream> 
#include <stdlib.h> 
class Lex { 
public: 
    Lex(istream& in, string fileName); 
    //Lex(); 
    //Lex(const Lex& l); 
    ~Lex(); 

    static const int INTLIT = 1; 
    static const int FLOATLIT = 2; 
    static const int STRLIT = 3; 
    static const int IDENT = 4; 
    static const int PLUS = 5; 
    static const int MINUS = 6; 
    static const int TIMES = 7; 
    static const int DIVIDE = 8; 
    static const int REM = 9; 
    static const int ASSIGN = 10; 
    static const int LPAREN = 11; 
    static const int RPAREN = 12; 
    static const int COMMA = 13; 
    static const int EQ = 14; 
    static const int LT = 15; 
    static const int LE = 16; 
    static const int GT = 17; 
    static const int GE = 18; 
    static const int NE = 19; 
    static const int SET = 20; 
    static const int PRINT = 21; 
    static const int WHILE = 22; 
    static const int DO = 23; 
    static const int END = 24; 
    static const int AND = 25; 
    static const int OR = 26; 
    static const int IF = 27; 
    static const int THEN = 28; 
    static const int ELSE = 29; 
    static const int ENDIF = 30; 
    static const int PROGRAM = 31; 
    static const int ENDOFFILE = 32; 
    static const int ERROR = 33;  
    int charIndex; 
    int lineIndex; 
    int spaceIndex; 
    int lineNum; 
    int lineLength[100]; 
    char ch; 
    bool hashCheck; 
    bool stopLoop; 
    Token nextToken(); 
    char nextChar();  
    char str[256][256]; 
    bool checkSet; 
    void printLex(); 
    string idents[256]; 
    int identCount; 
    friend ostream& operator<<(ostream& out, const Token& t); 
}; 
#endif 
#include "lex.h" 
#include "token.h" 
#include <iostream> 
#include <fstream> 
#include <stdlib.h> 

lex.cc在这里。

Lex::Lex(istream& in, string fileName) { 
    stopLoop = false; 
    charIndex = 0; 
    lineIndex = 0; 
    identCount = 0; 
    lineNum = 0; 
    hashCheck = false; 
    checkSet = false; 
    int tempSize; 
    ifstream file; 
    string temp; 
    for (int i = 0; i < 100; ++i) 
    lineLength[i] = 0; 
    if (!file.is_open()) { file.open(fileName.c_str()); }  
    while(!file.eof()) { 

    std::getline(file,temp);   
    tempSize = temp.size(); 

    for (int i = 0; i < tempSize; ++i) {  
     str[lineNum][i] = temp[i]; 
     lineLength[lineNum] += 1; 
    } 
    lineNum++; 
    } 
    file.close(); 
} 
Lex::~Lex() { 
delete [] str; 
} 
void Lex::printLex() {  
    charIndex = 0; 
    lineIndex = 0; 
    while (stopLoop == false) { 
    cout << nextToken(); 
    // cout << "Line index: " << lineIndex << endl; 
    } 
} 

ostream& operator <<(ostream& out, const Token& t) { 
    out << t.type() << " \t " << t.lexeme() << " \t \t " << (t.line() + 1) << " \t \t " << t.pos() << endl; 
    return out; 
} 
bool isReal(char ch) { 
    string alphabet = "abcdefghijklmnopqrstuvwxyz1234567890(){}<>+-/=!*,%&|."; 
    if (alphabet.find(ch) != alphabet.npos) return true; 
    else return false; 
} 
bool isNum(char ch) { 
    string specialChars = "1234567890."; 
    if (specialChars.find(ch) != specialChars.npos) return true; 
    else return false; 
} 
bool isNumFinal(string b) { 
    int length = b.length(); 
    const char* temp = b.c_str(); 
    bool henry = true; 
    for (int i = 0; i < length; ++i) { 
    if (henry == false) { break; } 
    henry = isNum(temp[i]); 
    } 
    return henry; 
} 

bool isSpecialChar(char ch) { 
    string specialChars = "(){}<>+-/=!*,%&|"; 
    if (specialChars.find(ch) != specialChars.npos) return true; 
    else return false; 
} 

char Lex::nextChar() { 
    if (lineIndex >= lineNum) { 
     // cout << "End of file reached\n"; 
     stopLoop = true; 
     return '#'; 
    }  
    else if (charIndex >= lineLength[lineIndex]) {  
     lineIndex++; 
     charIndex = 0; 
     return nextChar(); 
    } 
    else if (str[lineIndex][charIndex] == '#') {  
     hashCheck = true; 
     while (hashCheck = true) { 
     if (str[lineIndex][charIndex] == '#') { hashCheck = false; }   
     charIndex++; 
     if (charIndex > lineLength[lineIndex]) { 
      charIndex = 0; 
      lineIndex++; 
     } 
     } 
    }  
    else { 
     ch = str[lineIndex][charIndex]; 
     charIndex++; 
     return ch;    
    } 
    cout << "you shouldn't be here\n"; 
    return str[lineIndex][charIndex]; 
} 

Token Lex::nextToken() { 
    if (charIndex == lineIndex && charIndex == 0) { ch = nextChar(); }   
    while (ch == ' ') { ch = nextChar(); } 
    // cout << "CI: " << charIndex << endl; 
    string build; 
    int tempCharIndex = charIndex; 
    int tempLineIndex = lineIndex; 
    build += ch; 
    if (charIndex == lineIndex && charIndex == 0) { build = ""; } 
    if (checkSet == true) { 
    checkSet = false; 
    while (ch != ' ' && tempLineIndex == lineIndex) { 
     ch = nextChar(); 
     if (ch != ' ' && tempLineIndex == lineIndex) 
     build += ch;   
    } 
    idents[identCount] = build; 
    identCount++; 
    return Token(IDENT, build, tempLineIndex, tempCharIndex); 
    } 
    else if (isSpecialChar(ch)) {  
    switch(ch) { 
    case '(': 
     ch = nextChar(); 
     return Token(LPAREN, build, tempLineIndex, tempCharIndex); 
    case ')': 
    ch = nextChar(); 
     return Token(RPAREN, build, tempLineIndex, tempCharIndex); 
    case '{': 
    ch = nextChar(); 
     return Token(THEN, build, tempLineIndex, tempCharIndex); 
    case '}': 
    ch = nextChar(); 
     return Token(ENDIF, build, tempLineIndex, tempCharIndex); 
    case '+': 
    ch = nextChar(); 
     return Token(PLUS, build, tempLineIndex, tempCharIndex); 
    case '-': 
    ch = nextChar(); 
     return Token(MINUS, build, tempLineIndex, tempCharIndex); 
    case '/': 
    ch = nextChar(); 
     return Token(DIVIDE, build, tempLineIndex, tempCharIndex); 
    case '*': 
    ch = nextChar(); 
     return Token(TIMES, build, tempLineIndex, tempCharIndex); 
    case '=': 
     ch = nextChar(); 
     if (ch == '=') {  
     build += ch; 
     ch = nextChar();   
     return Token(EQ, build, tempLineIndex, tempCharIndex); 
     } 
     else { 

     return Token(ASSIGN, build, tempLineIndex, tempCharIndex); 
     } 
    case '>': 
     ch = nextChar(); 
     if (ch == '=') {  
     build += ch; 
     ch = nextChar(); 
     return Token(GE, build, tempLineIndex, tempCharIndex); 
     } 
     else return Token(GT, build, tempLineIndex, tempCharIndex); 
    case '<': 
     ch = nextChar(); 
     if (ch == '=') {     
     build += ch; 
     ch = nextChar(); 
     return Token(LE, build, tempLineIndex, tempCharIndex); 
     } 
     else return Token(LT, build, tempLineIndex, tempCharIndex); 
    case '!': 
     ch = nextChar(); 
     if (ch == '=') {  
     build += ch; 
     ch = nextChar(); 
     return Token(NE, build, tempLineIndex, tempCharIndex); 
     } 
     else return Token(ERROR, build, tempLineIndex, tempCharIndex); 
    case '%': 
    ch = nextChar(); 
     return Token(REM, build, tempLineIndex, tempCharIndex); 
    case '&': 
    ch = nextChar(); 
     return Token(AND, build, tempLineIndex, tempCharIndex); 
    case '|': 
    ch = nextChar(); 
     return Token(OR, build, tempLineIndex, tempCharIndex); 
    default: 
     return Token(ERROR, build, tempLineIndex, tempCharIndex); 
    } 
    } 
    else if (isNum(ch)) { 
    tempCharIndex = charIndex; 
    while (ch != ' ' && tempLineIndex == lineIndex) { 
     ch = nextChar(); 
     if (isSpecialChar(ch)) { 
     break; 
     } 
     if (ch != ' ' && tempLineIndex == lineIndex) 
     build += ch;  
    } 
    if (isNumFinal(build)) { 
     if (build.find('.') != build.npos) 
     return Token(FLOATLIT, build, tempLineIndex, tempCharIndex); 
     else return Token(INTLIT, build, tempLineIndex, tempCharIndex); 
    } 
    else return Token(ERROR, build, tempLineIndex, tempCharIndex); 
    } 
    else { 
    tempCharIndex = charIndex; 
    while (ch != ' ' && tempLineIndex == lineIndex) {  
     ch = nextChar(); 
     // cout << "ch: " << ch << endl; 
     if (ch != ' ' && tempLineIndex == lineIndex) 
     //cout << "inserted: " << ch << endl; 
     build += ch; 
    } 
    if (build.compare("while") == 0) 
     return Token(WHILE, build, tempLineIndex, tempCharIndex); 
    else if (build.compare("if") == 0) 
     return Token(IF, build, tempLineIndex, tempCharIndex); 
    else if (build.compare("print") == 0) 
     return Token(PRINT, build, tempLineIndex, tempCharIndex); 
    else if (build.compare("end") == 0) 
     return Token(ENDOFFILE, build, tempLineIndex, tempCharIndex); 
    else if (build.compare("else") == 0) 
     return Token(ELSE, build, tempLineIndex, tempCharIndex); 
    else if (build.compare("do") == 0) { return Token(DO, build, tempLineIndex, tempCharIndex); } 
    else if (build.compare("set") == 0) { 
     checkSet = true; 
     // cout << "CI: " << str[lineIndex] << endl; 
     return Token(SET, build, tempLineIndex, tempCharIndex); 
    } 
    else { 
     for (int i = 0; i < identCount; ++i) { 
     if (build.compare(idents[i]) == 0) { return Token(IDENT, build, tempLineIndex, tempCharIndex); } 
     } 
     cout << "build:" << build << ".\n"; 
     return Token(STRLIT, build, tempLineIndex, tempCharIndex); 
    } 
    } 
} 
+0

您是否已将'-Wall'传递给您的'g ++'编译器,还是您在编译时启用了所有警告? –

+0

您是否期望我们为您调试这段代码?这不是那种网站。 –

回答

8

除非您拨打new[],否则不要拨打delete[]str是您班级中的一个静态大小的数组,您既不需要new[]也不需要delete[]

你的类完全由处理自己的清理或不需要清理的对象组成,所以你的析构函数可以简单地为空。甚至不要声明它,编译器会在这种情况下为你提供正确的析构函数。

1

你有

Lex::~Lex() { 
delete [] str; 
} 

在你的代码,但str不是堆分配。这是你的一个数据成员Lex

我相信最近GCC调用的g++ -Wall -g可能会警告你这个错误。

2

str没有动态存储持续时间,但您试图在析构函数中将其删除。从析构函数中删除delete[] str

当您填写str时,您也没有进行任何边界检查。这可能会导致您覆盖导致其他问题的其他成员变量,并且可能是您遇到问题的原因。

// tempSize and/or lineNum may be greater than 256 
for (int i = 0; i < tempSize; ++i) {  
    str[lineNum][i] = temp[i]; 
    lineLength[lineNum] += 1; 
} 
0

好,因为你不需要删除STR阵列可言,它不是由你使用new,这样你就不需要调用delete创建。

VS给我: 警告C4154:删除数组表达式;转换为提供的指针