我一直试图让这些代码无法正常工作。 gdb告诉我在void Compiler :: GenerateCode_ToFile(char * filename)函数中有一个段错误,我已经手动将问题跟踪到该行的某个地方:
std::string tempfile = this->code->CodeGen( temp, AST_TYPE_UNDEF, symtab, 0);
但不是在它之前或之前。此外,它似乎在运行该虚函数的任何代码之前崩溃。
有人能在这看到问题吗?我只是看不出是什么导致它崩溃。 这是调用虚函数的函数:
void Compiler::GenerateCode_ToFile(char* filename){
char directory[MAX_PATH]; //Actually represents the full path.
strcpy( directory, this->cwd.c_str());
strcat( directory, filename);
if(this->isVerboseMode)
std::cout << "Source Output: " << directory << '\n';
std::fstream file( directory, std::ios::out);
int* temp = new int;
Symtable* symtab = new Symtable;
file << emit_core_code();
file << "\n\n";
std::string tempfile = this->code->CodeGen( temp, AST_TYPE_UNDEF, symtab, 0);
file.close();
}
这是由this-&gt;代码表示的类的定义。
/// CollectionExprAST - Expression class for multiple branches.
class CollectionExprAST : public ExprAST {
std::vector<ExprAST*>* Code;
public:
CollectionExprAST(std::vector<ExprAST*>* code) : Code(code) {}
virtual std::string CodeGen(int* GeneratedCodeOpType,int WantOpType,Symtable* symtab, int depth);
int GetType(void){return AST_TYPE_COLLECTION;};
void* GetCollection(void){return this->Code;};
void DebugPrint(int level);
};
这是它的超类:
/// ExprAST - Base class for all expression nodes.
class ExprAST {
public:
virtual ~ExprAST() {}
virtual std::string CodeGen(int* GeneratedCodeOpType,int WantOpType,Symtable* symtab, int depth) {return std::string("");};
virtual void DebugPrint(int level){return;};
virtual int GetType(void){return AST_TYPE_UNDEF;};
virtual void* GetCollection(void){return NULL;};
};
最后,这是被调用的虚函数(虽然在运行之前似乎崩溃了):
std::string CollectionExprAST::CodeGen(int* GeneratedCodeOpType,int WantOpType,Symtable* symtab, int depth)
{
Sleep(3000);
std::string ret;
int j=0;
for(;j<this->Code->size();j++){
int temp;
int i=0;
for(;i<depth;i++)
ret += "\t";
ret += (*this->Code)[j]->CodeGen(&temp,WantOpType,symtab, depth+1);
ret += '\n';
}
return ret;
}
我知道它在运行之前崩溃,因为Sleep()永远不会运行。
任何人都可以看到导致这种神秘段错误的错误吗?
提前致谢。
答案 0 :(得分:1)
原因是code
未分配或损坏。
在运行函数之前检查nil
,然后检查是否可以从该指针运行任何其他函数。第一个是显而易见的,后者可能意味着指针在某处被破坏了。
答案 1 :(得分:1)
我在你的例子中看不到你实际分配Code
成员变量的地方。它是一个指针,它指向的东西需要在某个时刻进行分配。
还有其他问题,但与您的崩溃没有直接关系。
首先,您永远不会删除symtab
中的temp
或GenerateCode_ToFile
。这是内存泄漏。就此而言,为什么你在世界上动态分配int
呢?只需在堆栈上声明一个int并将其地址传递给CodeGen
函数。如果可能,symtab
也是如此。
int i = 10;
SomeFuncThatTakesAPointer(&i);
实际上,仔细观察,你甚至不在函数中使用int*
参数,也不会在任何地方保存,所以只需完全摆脱它。
下一步...
std::vector<ExprAST*>* Code;
指向存储指针的向量和向量的指针几乎总是错误的。您正在阻止向量处理动态内存分配和释放。你可以在这一点上使用一个数组(好吧,如果你指定超出其边界的东西,数组不会为你增长,但仍然是不好的做法)。
Vectors使用名为RAII的模式来处理为您安全地分配和释放内存。当你维护一个指向向量的指针时,你会绕过那个过程,并且需要自己调用向量上的delete
。
当您将指针存储在向量中时,再次阻止向量释放其存储的对象。它将动态存储指针并在它们上调用delete
,但这不会释放原始指针所指向的内容。
C ++是一门复杂的语言。我建议花一些时间来学习更多关于内存管理和RAII之类的模式,这可以简化你的过程。