我一直有一个分割错误,我想不出来。导致分割错误的功能如下:
Expression *IntegerLiteral_init(int intgr) {
Expression *the_exp = safe_alloc(sizeof(Expression));
the_exp->type = expr_IntegerLiteral;
the_exp->expr->intgr = intgr;
the_exp->exec_count = 0;
return the_exp;
}
定义表达式:
typedef struct {
expr_type type;
u_expr *expr;
int exec_count;
} Expression;
定义了表达式和表达式类型:
typedef union {
char *ident;
int intgr;
} u_expr;
typedef enum {
expr_Identifier,
expr_IntegerLiteral
} expr_type;
expr_type
是expr_IntegerLiteral
和expr_Identifier
的枚举。根据gdb,segfult是在线路上引起的:
the_exp->expr->intgr = intgr;
。奇怪的是,它并不总是导致segfault—如果我以这种方式调用函数,就会发生segfault:
Expression *e = IntegerLiteral_init(0);
但在我程序的另一部分中,我称之为使用:
Expression *e;
...
e = IntegerLiteral_init(
(int)strtol(num_str, (char **)NULL, 10));
没有任何问题。
num_str
已从某些输入中解析,其值为"0"
。我不明白,如果给定的
IntegerLiteral_init()
参数相同,为什么我调用intgr
的上下文会影响此segfult是否发生。如果有人能告诉我,我将不胜感激。 最佳答案
线路
the_exp->expr->intgr = intgr;
正在写入未初始化的指针。您为
the_exp
分配了内存,但没有为the_exp->expr
分配内存。最简单的解决方法可能是通过值而不是指针将Expression
更改为u_expr
。typedef struct {
expr_type type;
u_expr expr;
int exec_count;
} Expression;
如果您不能这样做,
IntegerLiteral_init
可以更改为分配the_exp->expr
的内存Expression *IntegerLiteral_init(int intgr) {
Expression *the_exp = safe_alloc(sizeof(Expression));
the_exp->type = expr_IntegerLiteral;
the_exp->expr = safe_alloc(sizeof(*the_exp->expr));
the_exp->expr->intgr = intgr;
the_exp->exec_count = 0;
return the_exp;
}
如果您尝试后一种方法,请确保在释放
the_exp->expr
时也释放the_exp
。关于为什么有时
IntegerLiteral_init()
看起来有效,访问未分配的内存会导致未定义的行为。有时你很幸运,但这会立即崩溃,让你可以使用调试器来查看问题所在。其他时候,你运气不好,程序继续执行,但在很长一段时间后,当另一位代码试图访问内存IntegerLiteral_init()
时崩溃。