1

我一直试图让这段代码工作但没有成功。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->code所代表的类的定义。

/// 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() 永远不会运行。

谁能看到导致这个神秘段错误的错误?

提前致谢。

4

2 回答 2

1

I see nowhere in your example where you actually allocate the Code member variable. It is a pointer and what it points to needs to be allocated at some point.

There are other problems as well, though not directly related to your crash.

First, you never delete symtab or temp in GenerateCode_ToFile. This is a memory leak. For that matter, why in the world are you dynamically allocating an int there? Just declare an int on the stack and pass its address to the CodeGen function. Same goes for symtab if possible.

int i = 10;
SomeFuncThatTakesAPointer(&i);

Actually, looking more closely, you don't even use the int* parameter in the function and it isn't saved anywhere, so just get rid of it entirely.

Next...

std::vector<ExprAST*>* Code;

Pointers to vectors and vectors that store pointers are almost always wrong. You are preventing the vector from handling dynamic memory allocation and deallocation for you. You may as well just use an array at this point (ok, an array doesn't grow for you if you assign something beyond its boundaries, but still, bad practice).

Vectors use a pattern called RAII to handle safely allocating and deallocating memory for you. When you maintain a pointer to a vector you circumvent that process and are required to call delete on the vector yourself.

When you store pointers in a vector you, once again, prevent the vector from deallocating its stored objects. It will store the pointers themselves dynamically and call delete on them, but this will not deallocate what the original pointer was pointing to.

C++ is a complex language. I suggest spending some time learning more about memory management in general and patterns like RAII which can simplify the process for you.

于 2012-04-05T00:03:39.773 回答
1

原因是code未分配或损坏。

在运行函数之前检查nil,然后检查是否可以从该指针运行任何其他函数。第一个很明显,后者可能意味着指针在某处损坏。

于 2012-04-04T23:54:49.480 回答