_block_type_is_valid phead- nblockuse on delete command

_block_type_is_valid phead- nblockuse on delete command

本文关键字:on delete command nblockuse valid block type is phead-      更新时间:2023-10-16

所以我知道这是一个非常常见的错误,但我对C++非常陌生,我们正在将它用于编程语言类,这个错误让我陷入了困境。删除解析器;线是导致这个错误的线,我不知道为什么。

Turtle2.cpp

#include <iostream> 
#include <sstream> 
#include <string> 
#include <fstream> 
#include "scanner.h" 
#include "parser.h"
using namespace std; 
int main(int argc, char* argv[]) { 
//string line; 
if (argc != 2) { 
    cout << "Usage: turtle filename" << endl; 
    return 0; 
} 
char* filename = argv[1];
cout << "filename is " << filename << endl; 
ifstream in(filename); 
Parser * parser = new Parser(&in); 
AST* tree = parser->parse(); 
tree->evaluate(); 
delete tree; 
delete parser;   //This is the line that causes the error!
return 0; 
} 

parser.cpp

#include "parser.h"
#include "calcex.h"
#include <string>
#include <sstream>
Parser::Parser(istream* in) {
scan = new Scanner(in);
}
Parser::~Parser() {
try {
  delete scan;
} catch (...) {
}
}
AST* Parser::parse() {
AST* returnValue = Prog();
cout << "We are still ok1" << endl;
return returnValue;
}
AST* Parser::Prog() {
AST* result = StmtList();
Token* t = scan->getToken();
if (t->getType() != eof) {
    cout << "Syntax Error: Expected EOF, found token at column " << t->getCol() << endl;
throw ParseError;
}
cout << "We are still ok2" << endl;
return result;
}
AST* Parser::StmtList() {
AST* result = Statement();
Token* t = scan->getToken();
scan->putBackToken();   
if (t->getType() != eof) {
  AST* result = StmtList();
        return result;
}
return result;
}
AST* Parser::Statement() {
float num1;
float num2;
stmtNode* node;
Token* t = scan->getToken();
/*if (turtle->getType() != keyword || turtle->getLex() != "turtle"){
    cerr <<"expected turtle" << endl;  //print to standard error stream
    throw ParseError;
}*/
if (t->getType() == keyword && t->getLex() == "turtle"){
    t = scan->getToken();
    if (t->getType() == dot){
        t = scan->getToken();
        if (t->getType() == keyword && t->getLex() == "goto"){
            t = scan->getToken();
            if (t->getType() == lparen){
                t = scan->getToken();
                if (t->getType() == number){
                    istringstream in(t->getLex());
                    in >> num1;
                    t = scan->getToken();
                    if (t->getType() == comma){
                        t = scan->getToken();
                        if (t->getType() == number){
                            istringstream in(t->getLex());
                            in >> num2;
                            t = scan->getToken();
                            if (t->getType() == rparen){
                                cout << "Good" << endl;
                                node = new stmtNode(num1,num2);
                                cout << "X is " << node->getX() << endl;
                                cout << "Y is " << node->getY() << endl;
                            }
                        }
                    }
                }
            }
        }
    }
}
else{
    cout << "bad" << endl;
}
return node;
}

scanner.cpp

#include "scanner.h"
#include "calcex.h"
#include <iostream>
#include <string>
using namespace std;
//Uncomment this to get debug information
//#define debug
const int numberOfKeywords = 2;
const string keywd[numberOfKeywords] = { //defining the keywords
string("turtle"), string("goto")
};
int isLetter(char c) { //c is bigger or equal to 'a' and small or equal to 'z'. same     for captial versions
return ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'));
}
int isDigit(char c) { //c is bigger or equal to '0' or smaller or equal to '9' 
return (c >= '0' && c <= '9');
}
int isWhiteSpace(char c) { //c is a space, tab or newline
return (c == ' ' || c == 't' || c == 'n');
}
Scanner::Scanner(istream* in): //scanner constructor
inStream(in),
lineCount(1),
colCount(0),
needToken(true),
lastToken(0)
{}
Scanner::~Scanner() { //scanner de-constructor
try {
  delete inStream;
} catch (...) {}
}
void Scanner::putBackToken() { //method?
needToken = false;
}
Token* Scanner::getToken() { //method?
if (!needToken) {
  needToken=true;
  return lastToken;
}
Token* t;
int state=0;
bool foundOne=false;
char c;
string lex;
TokenType type;
int k;
int column, line;
c = inStream->get();
while (!foundOne) {
  colCount++;
  switch (state) {
     case 0 : 
        lex = "";
        column=colCount;
        line = lineCount;
        if (isLetter(c)) state=1;
        else if (isDigit(c)) state=2;
        else if (c=='.') state=3;
        else if (c==',') state=4;
        else if (c=='(') state=5;
        else if (c==')') state=6;
        else if (c=='n') {
           colCount=0;
           lineCount++;
        }
        else if (isWhiteSpace(c));
        else if (inStream->eof()) {
           foundOne=true;
           type=eof;
        }
        else {
           cout << "Unrecognized Token found at line " << line <<
              " and column " << column << endl;
           throw UnrecognizedToken;
        }
        break;
     case 1 :
        if (isLetter(c) || isDigit(c)) state=1;
        else {
           for (k=0;k<numberOfKeywords;k++)
              if (lex == keywd[k]) {
                 foundOne = true;
                 type = keyword;
              }
           if (!foundOne) {
              type = identifier;
              foundOne = true;
           }
        }
        break;
     case 2 :
        if (isDigit(c)) state=2;
        else {
           type = number;
           foundOne=true;
        }
        break;
     case 3 :
        type = dot;
        foundOne = true;
        break;
     case 4 :
        type = comma;
        foundOne = true;
        break;
     case 5 :
        type = lparen;
        foundOne=true;
        break;
     case 6 :
        type = rparen;
        foundOne=true;
        break;
  }
  if (!foundOne) {
     lex = lex + c;
     c = inStream->get();
  }
 }
 inStream->putback(c);
 colCount--;
 if (type == number || type == identifier || type == keyword) {
  t = new Token(type,new string(lex),line, column);
 }
 else {
  t = new Token(type,new string(lex),line,column);
 }
 #ifdef debug
 cout << "just found " << lex << " with type " << type << endl;
 #endif
 lastToken = t;
 return t;
}

我不知道这是否足以帮助你们,如果你需要更多的东西,只要问一下,这不是秘密或任何事情:)我知道它是解析器的构造函数,但我不知道如何修复它,也不知道为什么会发生这种情况。。。我添加了scanner.cpp,因为有些人认为问题可能存在于它的解构器中,所以我希望这会有所帮助。

失败的原因是您在堆栈上分配的东西上使用了delete

注意在堆栈上创建ifstream的ifstream in(filename);和Scanner的析构函数中的delete inStream;的组合。

最简单的建议是在堆上分配in,而不是ifstream *in = new ifstream(filename)之类的。

一个更好的解决方案可能是让其他类(Scanner、Parser等)通过引用获取ifstream,并避免指针,除非需要它们。

您正试图删除Scanner的析构函数中的堆栈变量。

Parser * parser = new Parser(&in); 
Parser::Parser(istream* in) {
scan = new Scanner(in);
}
Parser::Parser(istream* in) {
scan = new Scanner(in);
}
Parser::~Parser() {
try {
  delete scan;
} catch (...) {
}
}
Scanner::~Scanner() { //scanner de-constructor
try {
  delete inStream;
} catch (...) {}
}