我正在为学校项目编写一些代码。这是一个表达树,以中缀符号保存数字和运算符。 Tree structure
树具有以下结构:
typedef struct
{
char the_operator;
struct operand_node_tag *left_operand;
struct operand_node_tag *right_operand;
} operator_node;
typedef struct operand_node_tag
{
enum {operator_type, number_type} tree_node_type;
union
{
operator_node the_operator_node;
int the_number;
};
} tree_node;
我有一个可以动态创建操作员节点的函数:
tree_node *create_expression(char op, tree_node *l, tree_node *r)
{
// Dynamically reserve memory for a tree_node of type operator_type.
tree_node *newTreeNode = malloc(sizeof(tree_node));
if (newTreeNode == NULL)
{ //Return NULL if there is no available memory.
return NULL;
}
// Set the_operator to op, left_operand to l and right_operand to r
newTreeNode->the_operator_node.the_operator = op;
newTreeNode->the_operator_node.left_operand = l;
newTreeNode->the_operator_node.right_operand = r;
newTreeNode->tree_node_type = operator_type;
// and return the tree_node
return newTreeNode;
}
以及一个可以动态创建数字节点的函数:
tree_node *create_number_node(int i)
{
// Dynamically reserve memory for a tree_node of type number_type.
tree_node *newTreeNode = malloc(sizeof(tree_node));
if (newTreeNode == NULL) { //Return NULL if there is no available memory.
return NULL;
}
//Set the node type to number
newTreeNode->tree_node_type = number_type;
// Set the_number to i and return the tree_node
newTreeNode->the_number = i;
// and return the tree_node
return newTreeNode;
}
这些功能对我来说很好用。释放分配的内存时出现问题。为此,我编写了以下功能:
void free_expression_tree(tree_node **pnode)
{
// Free all dynamically reserved memory and set *pnode to NULL.
if ((*pnode)->the_operator_node.left_operand && (*pnode)->tree_node_type == operator_type)
{
free_expression_tree(&(*pnode)->the_operator_node.left_operand);
(*pnode)->the_operator_node.left_operand = NULL;
}
if ((*pnode)->the_operator_node.right_operand && (*pnode)->tree_node_type == operator_type)
{
free_expression_tree(&(*pnode)->the_operator_node.right_operand);
(*pnode)->the_operator_node.right_operand = NULL;
}
printf("Free: ");
if ((*pnode)->tree_node_type == operator_type)
{
printf("%c, ", (*pnode)->the_operator_node.the_operator);
free(*pnode);
printf("%d, \n", (*pnode)->the_operator_node.the_operator);
}
else
{
printf("%d, ", (*pnode)->the_number);
free(*pnode);
printf("%d, \n", (*pnode)->the_number);
}
}
它循环遍历给定节点并释放较低级别的所有节点。该功能在调试器(GCC)中似乎可以正常工作,在控制台中给出以下结果:
Free: 12, 3277136,
Free: 40, 3277136,
Free: 23, 3277136,
Free: 3, 3296384,
Free: -, -18,
Free: /, -18,
Free: 2, -17891602,
Free: *, -18,
Free: +, -18,
我正在执行free()函数之前和之后打印数字/运算符。似乎在这里工作正常。
现在这是相同的结果,但是实际上我正在运行.exe:
Free: 12, 3735888,
Free: 40, 3735888,
Free: 23, 3735888,
Free: 3, 3763520,
Free: -, -,
Free: /, /,
Free: 2, 2,
Free: *, *,
Free: +, +,
我假设这与编译器设置有关,但是我一无所知。我关闭了优化功能。
你们有什么建议吗?
您有
free(*pnode);
直接后跟例如
printf("%d, \n", (*pnode)->the_operator_node.the_operator);
在第二条语句中,您取消引用了刚传递给free
的指针,因此该指针所指向的内存不再归您的程序所有,并且任何取消引用该指针的尝试都将导致undefined behavior。] >
一旦释放内存,您就无法使用内存。