C初始化变量的值在比较后自行更改

时间:2017-03-29 23:40:27

标签: c

我在C中实现了一个简单的树结构。程序显示了一些奇怪的行为,我能够将它缩小到一个地方,其中值存储在内存位置并通过使用指针访问意外地更改。它是可复制的,但只能在递归函数的几次运行(具体取决于输入)之后发生。它位于'while'语句标题的某处。我已经在'while'之前检查了所有指针指向具有预期的,明确定义的内容的存储器单元。最让我感到烦恼的是,即使我将值的副本分配给另一个变量,变量也会变化。我不知道怎么可能,虽然我怀疑有一些显而易见的东西我不知道。以下是相关的代码片段。

typedef struct _Node {
    int root;
    struct _Node *children;
    struct _Node *next;
    struct _Node *previous;
} Node;

int delete_subtree_aux(Node *n) {

    Node *children = get_children(n);

    int i = children->root;
    int j = i;

    // At this point i and j both equal e.g. -4

    while (!(children->next->root == children->root)) {

        i = children->root; 

        // At this point i equals -3

        assert(i == j);

        // And j equals -3 too!

        delete_subtree_aux(get_first(children));

    }

    free_node(children);
}

非常感谢所有帮助!

编辑:

free_node(children);设置了额外的断点后,我注意到执行了指令的顺序已经关闭。同时,程序直接从free_node(children);循环到循环内部,绕过while条件检查。 'n','i','j'和'children'一起变化并对应不同的函数输入。设置数据断点显示不同的'j'位于两个不同的内存地址。

在我看来,由于某种原因,这个函数的一些实例以某种方式在并列中执行,但这不是我的意图。我的后续问题是,在这种情况下释放内存会导致错误吗?如果是,我该怎么做才能解决它?

编辑2: 上面代码中调用的其他函数的来源:

int free_node(Node *n) {
    free(n);
}

Node *get_children(Node *n) {
    return n->children;
}

Node *get_first(Node *list) {
    return list->next;
}

1 个答案:

答案 0 :(得分:0)

问题是当get_first(children) == get_last(children) while循环应该有它的最后一次迭代。但是,delete_subtree_aux无法更新children->next指向的位置。当此地址的节点children空闲时,while循环而不是停止,尝试再做一次迭代(因为children->next指向某些Node - 就像垃圾一样在内存中与children不同。但是,这一次,它会尝试访问免费的children,这当然会导致错误。

神奇地改变了儿童,儿童'和' n'在while之前和内部之间是查看堆栈上不同级别的递归函数的结果,正如@Holsety在评论中指出的那样。