我正在创建一个编译器,并开始创建我的解析树结构。
我有一个可以包含子节点或不包含子节点的“节点”。
typedef struct Node {
int node_type;
union {
char* string;
int number;
struct Node* nodes;
} node_data;
} Node;
这些功能组装/打印它
Node* MakeNodeFromString(char* mystring) {
Node* mynode = (Node*) malloc(sizeof(Node));
mynode->node_data.string = strdup(mystring);
mynode->node_type = 0; // @TODO not 3
return mynode;
}
Node* MakeTwoBranchNode(int nodetype, Node* a, Node* b) {
Node* mynode = (Node*) malloc(sizeof(Node));
mynode->node_type = 2; // @TODO not 3
mynode->node_data.nodes = malloc(2 * sizeof(Node*));
mynode->node_data.nodes[0] = *a; mynode->node_data.nodes[1] = *b;
return mynode;
}
void printtree (Node *n, int level) {
if (!n) return;
printf ("start %d\n", n->node_type);
switch (n->node_type) {
case 2:
printf ("%*c2\n", level, ' ');
printtree (&n->node_data.nodes[0], level+1);
printtree (&n->node_data.nodes[1], level+1);
break;
case 0:
printf ("%*c%s\n", level, ' ', n->node_data.string);
break;
}
printf ("end %d\n", n->node_type);
}
每当我组装一棵树时,我都会得到段错误,要么 printf'ing 要么 strlen'ing 我的字符串。我已经尝试过 strdup、strcpy 等。我很确定它不是 MakeTwoBranchNode 失败的,因为我可以创建大的数字树(不包括代码)。但我不确定。
这是一个代码示例,说明它在我的机器上会发生并且不会发生段错误
int main() {
// Works
printtree(
MakeTwoBranchNode(3,
MakeNodeFromString("first string"),
MakeNodeFromString("second string")
),
1
);
// Fails
printtree(
MakeTwoBranchNode(3,
MakeTwoBranchNode(3,
MakeNodeFromString("first string"),
MakeNodeFromString("second string")
),
MakeNodeFromString("third string")
),
1
);
}
如果您运行此示例(并且可以理解其神秘的输出),您将在 printf(n->node_data.string) 期间看到它的段错误。