使用malloc()

时间:2017-12-01 00:15:36

标签: c++ pointers memory memory-management

我目前正致力于使用C ++创建一个小型编译器。我已经定义了以下对象:

struct ValueNode
{
    std::string name;
    int value;
};

struct StatementNode
{
    StatementType type;

    union
    {
        struct AssignmentStatement * assign_stmt;
        struct PrintStatement * print_stmt;
        struct IfStatement * if_stmt;
        struct GotoStatement * goto_stmt;
    };

    struct StatementNode * next; // next statement in the list or NULL
};

我已经定义了一系列与语言中不同类型语句相关的函数。其中一个函数称为parse_assignment_stmt()。我正在经历的分段错误发生在此函数中,在尝试为最近分配的内存分配值之后立即发生。这是函数:

struct StatementNode* parse_assign_stmt() {

    //Object to be returned. Holds an object representing a statement
    //made within the input program.
    struct StatementNode* st = (struct StatementNode*)malloc(sizeof(struct StatementNode));

    st->type = ASSIGN_STMT;

    //First token should be an ID. Represents memory location we are assigning to.
    Token tok = lexer->GetToken(); 

    if(tok.token_type == ID) {

        //Second token in an assignment should be an equal sign
        Token tok2 = lexer->GetToken();

        if (tok2.token_type == EQUAL) {

            //This function reads the next token, makes sure it is of type NUM or ID, then creates and returns a ValueNode containing the relevant value.
            struct ValueNode* rhs1 = parse_primary();

            Token tok3 = lexer->GetToken();

            //Assignment format for this logical branch: "x = 5;"
            if(tok3.token_type == SEMICOLON) {
                //first type

                //Allocate memory for objects needed to build StatementNode st
                struct AssignmentStatement* assign_stmt = (struct AssignmentStatement*)malloc(sizeof(struct AssignmentStatement));

                struct ValueNode* lhs = (struct ValueNode*)malloc( sizeof(struct ValueNode));

                printf("Name: %s, Value: %d\n", lhs->name.c_str(), lhs->value);


                //PROBLEM ARISES HERE***
                //lhs->name = tok.lexeme;               

                //return the proper structure
                return st;
            }
            else if(tok3.token_type == PLUS || tok3.token_type == MINUS || tok3.token_type == DIV || tok3.token_type == MULT) {
                //second type

                //TODO
            }
            else {
                printf("Syntax error. Semicolon or operator expected after first primary on RHS of assignment.");
                exit(1);
            }
        }
        else {
            //not of proper form
            printf("Syntax error. EQUAL expected after LHS of assignment.");

            exit(1);
        }
    }
    else {
        //Not of proper form. Syntax error
        printf("Syntax error. ID expected at beginning of assignment.");

        exit(1);
    }
}

基本上,我为新的ValueNode分配内存以创建变量lhs。我正在立即打印出名称和值字段,以确保没有任何内容。在我的编译器输出中(顺便说一下,我使用g ++),它告诉我名称是(null),值是0,这是预期的。一旦我取消注释该行

lhs->name = tok.lexeme;

我遇到了分段错误。在这一点上,我不知道会出现什么问题。我正在创建变量,使用malloc为该位置分配内存,确保没有存储任何内容,然后立即尝试写入值。它总是给我一个分段错误。

这是通过stdin提供给程序的输入程序(.txt文件)。

i;
{
    i = 42 ; 
    print i;
}

我尝试使用calloc()代替,因为这应该确保在返回指针之前清除内存,但这并没有改变任何东西。任何建议都会很精彩。谢谢!

2 个答案:

答案 0 :(得分:0)

如果问题出现在该行中:

lhs->name = tok.lexeme; 

然后我保证问题在于lhstok.lexeme

在此之前,您似乎已确认lhs可以使用:

printf("Name: %s, Value: %d\n", lhs->name.c_str(), lhs->value);

那么令牌结构出现问题的可能性就会大大增加。

但是,我们不应该猜测,您应该能够将代码加载到一个好的调试器(甚至是gdb,在一个紧凑的(a)中,在违规行设置一个断点,实际上变量以查看它们是否符合预期。或者,至少在尝试使用它之前打印出更多东西。

除此之外:在大学教授的第一个课程不是调试101,这一直是我的一个小问题。这是我教儿子一开始的第一个的事情做Python开发。

(a) Pax ducks for cover: - )

答案 1 :(得分:0)

经过进一步研究,我发现在为我的ValueNode对象分配内存(使用malloc())时(由于某种原因,只有这些),malloc()返回一个指向无法访问的内存的指针。尝试打印我的ValueNode结构时在gdb中收到的错误是:

{name =<'错误读取变量:无法访问地址0xfffffffe8的内存>,值= 42}

不幸的是,我无法使用malloc()找到为此对象分配内存的方法。然而,我设法实现的解决方法是在ValueNode的结构定义中创建构造函数,然后使用" new"创建对象并为我分配内存,而不是试图强制malloc()工作。回想起来,我可能应该使用这种比malloc()更简单的方法来开始。