我的程序执行正常,但最后,当我调试它时,它在调用我的析构函数后出现了分段错误。我不确定问题的原因是什么。我发布了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 :(得分:8)
除非您致电delete[]
,否则请勿致电new[]
。 str
是您班级中的一个静态大小的数组,您既不需要new[]
也不需要delete[]
。
您的类完全由对象组成,这些对象将处理自己的清理,或者不需要清理,因此您的析构函数可以简单地为空。甚至不要声明它,在这种情况下编译器将为您提供正确的析构函数。
答案 1 :(得分: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;
}
答案 2 :(得分:1)
你有
Lex::~Lex() {
delete [] str;
}
代码中的,但str
未分配堆。它是Lex
类
我相信最近调用的GCC g++ -Wall -g
可能会警告你这个错误。
答案 3 :(得分:0)
好吧,因为你根本不需要删除str数组,它不是由你使用new
创建的,所以你不需要调用delete
。