分割内存位置后,将内存分配给MALLOC()时分割故障

Segmentation fault when accessing memory location after allocating memory with malloc()

本文关键字:分割 内存 故障 MALLOC 分配 位置      更新时间:2023-10-16

我当前正在使用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: %dn", 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);
    }
}

本质上,我正在为创建变量LHS的新值分配内存。我立即打印出名称和价值字段,以确保没有任何目前的情况。在我的编译器输出(顺便说一句,我正在使用G )中,它告诉我名称为(null),值为0,这是预期的。我一开始就注销

lhs->name = tok.lexeme;

我会得到一个分段故障。在这一点上,我不知道会出现什么问题。我正在创建变量,使用malloc将内存分配给位置,确保那里没有任何存储的东西,然后立即尝试编写一个值。而且它总是给我一个细分错误。

这是通过STDIN送入程序的输入程序(.txt文件)。

i;
{
    i = 42 ; 
    print i;
}

我尝试使用Calloc(),因为这应该确保在返回指针之前清除内存,但这并没有改变任何内容。任何建议都是很棒的。谢谢!

如果问题出现在行中:

lhs->name = tok.lexeme; 

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

由于在此之前,您似乎已经确认lhs可以:

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

然后,这是令牌结构飞涨的机会。

但是,我们不需要推测,您应该能够将代码加载到良好的调试器中(甚至是gdb,在Pinch (a))中,在有问题的线,实际上查看变量,以查看它们是否如预期的。或者,最低限度,在尝试使用之前打印出更多的东西。


旁边:第一课程在大学教授的课程一直是我的虫子。进行Python开发。


(a) Pax Ducks用于封面: - )

在进行进一步调查后,我发现,当对我的valueNode对象(以及出于某种原因,仅这些)分配内存(使用malloc())时,malloc()正在返回指向无法访问的内存。试图打印我的ValueNode结构时,我在GDB中收到的错误是:

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

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