我必须在Flex/Yacc上做这个项目,在那里我必须计算一个Insiemistic表达式的抽象树。但真实的问题在C代码中。
我创建了这个函数,它创建了一个节点:
node_t * createNode(node_content_t nodecontent, int nodetype){
node_t *newNode = (node_t *) malloc(sizeof(node_t * ));
if(nodetype == 0){
newNode->content = (node_content_t)strdup(nodecontent.string);
}
else
newNode->content = nodecontent;
newNode->type = nodetype;
newNode->leftChild = NULL;
newNode->rightChild = NULL;
printf("Right Child in createNode: %p\n", newNode->rightChild);
return newNode;
}
正如你所看到的,left和right child都被初始化为null。但是,当我试图打印右子函数的指针值时,它改变了值(通常为0x 23或0x 53),导致分段错误。
node_t和node_content_t定义如下
typedef union{
char* string;
char singleletter;
}node_content_t;
typedef struct node node_t;
struct node{
node_content_t content;
int type; //0 for string, 1 for char
node_t *leftChild;
node_t *rightChild;
};
当我试图在createNode
中打印指针时,结果是0x 0,我在这个函数printNode中打印它,这应该打印整个树:
void printNode(node_t *n, size_t indent) {
char *indentation = malloc(sizeof(char) * indent);
for (size_t i = 0; i < indent; ++i) {
indentation[i] = ' ';
}
printf("LeftChild: %p\n", n->leftChild);
printf("RightChild: %p\n", n->rightChild);
switch (n->type) {
case 0: printf("%s%s\n", indentation, n->content); break;
case 1: printf("%s%c\n", indentation, n->content); break;
}
if (n->leftChild != NULL){
printNode(n->leftChild, indent+2);
}
if (n->rightChild != NULL){
printf("RightChild: %p\n", n->rightChild); //there
printNode(n->rightChild, indent+2);
}
printf("Non ci sono figli\n");
}
就像我说的,值改变了,所以函数不起作用,有什么想法吗?如果不在函数addChild中,我不会修改rightChild的值:
void addChild(node_t *parent, node_t *child) {
printf("Addchild\n");
printf("Right Child in createNode: %p\n", parent->rightChild);
if(parent->leftChild == NULL)
parent->leftChild = child;
else if(parent->rightChild == NULL && strcmp(parent->content.string, "co") != 0 ){
parent-> rightChild = child;
printf("Aggiunto figlio destro\nContent: %c\nType: %d\n", child->content, child->type);
}
else
printf("Error during child adding\n");
}
2条答案
按热度按时间v8wbuo2f1#
问题一:
1.这为
node_t *
分配了足够的空间;不是你想要的node_t
结构。1.铸造是不必要的(可能是有害的。
1.最好使用变量的 name 而不是它的 type(减少将来的维护)。
malloc()
可能会失败。习惯检查返回值。养成习惯吧!问题二:
indentation
在每次调用这个函数时都被分配,并且它永远不会被free()
'd。内存泄漏(加速分配失败的发生。)
indentation
不是 *null终止的 *,并且不能被视为C字符串。摆脱执行分配的行,并利用
printf()
的功能。例如:%*s
从下一个参数中获取 * 字段宽度说明符 *,在本例中为indent
。然后,它将字符串打印到一个如此宽的字段中,在本例中为""
。结果是每行上所需空格数的 * 前缀 *。ffscu2ro2#
问题在于
malloc()
调用:node_t *newNode = (node_t *) malloc(sizeof(node_t * ));
只分配指针的大小。要求解,请将其更改为
node_t *newNode = malloc(sizeof *newNode);
。