简体   繁体   English

_block_type_is_valid phead-在删除命令上使用nblock

[英]_block_type_is_valid phead- nblockuse on delete command

So I know this is a pretty common error, but I'm very new to C++, we are using it for a programing languages class, and this error has me stuck. 因此,我知道这是一个非常常见的错误,但是我对C ++还是很陌生,我们正在将其用于编程语言类,并且这个错误使我陷入了困境。 The delete parser; 删除解析器; line is the line that causes this error, and I cannot figure out why. line是导致此错误的行,我无法弄清楚原因。

Turtle2.cpp 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;

}

I don't know if that is enough code to help you guys out or not, if you need anything more just ask, its not a secret or anything :) I know its the de-constructor for parser, but I have no idea how to fix it, or really why this is happening... I've added scanner.cpp, because some ponited out that the problem could be in its deconstructor, so I hope that helps. 我不知道那是否足够的代码来帮助你们,如果您需要更多的只是问问,那不是秘密或其他什么:)我知道它是解析器的反构造函数,但是我不知道如何要修复它,或者实际上是为什么要解决此问题...我添加了scan.cpp,因为有人认为问题可能出在其解构函数中,所以我希望对您有所帮助。

The reason why this is failing is that you are using delete on something that was allocated on the stack. 失败的原因是您对堆栈上已分配的内容使用了delete

Note the combination of ifstream in(filename); 注意ifstream in(filename);的组合ifstream in(filename); , creating an ifstream on the stack and the delete inStream; ,在堆栈上创建ifstream并delete inStream; in the destructor of Scanner. 在Scanner的析构函数中。

The easiest suggestion would be to allocate in on the heap, whish ifstream *in = new ifstream(filename) or whatnot. 最简单的建议是将分配in堆上,哗哗ifstream *in = new ifstream(filename)或诸如此类。

A better solution would probably be to have the other classes(Scanner, Parser, etc) take the ifstream by reference, and avoid pointers unless they are needed. 更好的解决方案可能是让其他类(Scanner,Parser等)通过引用获取ifstream,并避免使用指针,除非需要它们。

You are trying to delete a stack variable, in the destructor of Scanner. 您试图在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 (...) {}
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM