free()在调试器中工作,但不在运行模式下

问题描述 投票:1回答:1

我正在为学校项目编写一些代码。这是一个表达树,以中缀符号保存数字和运算符。 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: +, +, 

我假设这与编译器设置有关,但是我一无所知。我关闭了优化功能。

你们有什么建议吗?

c struct union expression-trees infix-notation
1个回答
0
投票

您有

free(*pnode);

直接后跟例如

printf("%d, \n", (*pnode)->the_operator_node.the_operator);

在第二条语句中,您取消引用了刚传递给free的指针,因此该指针所指向的内存不再归您的程序所有,并且任何取消引用该指针的尝试都将导致undefined behavior。] >

一旦释放内存,您就无法使用内存。

© www.soinside.com 2019 - 2024. All rights reserved.