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

C比较后,初始化变量的值自行改变,c,C,我正在用C实现一个简单的树结构。程序显示了一些奇怪的行为,我能够将它缩小到一个地方,在这个地方,存储在内存位置并使用指针访问的值会意外地发生变化。它是可复制的,但仅在递归函数运行几次(取决于输入的确定性)后发生。它位于while语句头的某个地方。我在“while”之前检查过,所有指针都指向预期的、定义良好的等内容的内存单元。最让我头疼的是,即使我将值的副本分配给另一个变量,该变量也会发生变化。我不知道这是怎么可能的,尽管我怀疑我明显遗漏了什么。下面是相关的代码片段 typedef struct

我正在用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_节点(子节点)设置额外断点后我注意到执行指令的顺序有问题。一次,程序直接从
自由节点(子节点)运行至环路内部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;
}

问题是当
get\u first(children)==get\u last(children)
while循环应该有它的最后一次迭代。但是,
delete_subtree_aux
无法更新
children->next
指向的位置。当位于该地址的节点的
子节点
空闲时,while循环不会停止,而是尝试再进行一次迭代(因为
子节点->下一个
指向一些
节点
——类似内存中的垃圾,与
子节点
不同)。然而,这一次,它试图访问免费的
子项
,这当然会导致错误


正如@Holsety在评论中指出的那样,

之前和
内部之间“i”、“j”、“children”和“n”的神秘变化是查看堆栈上不同级别递归函数的结果。

在调试器下运行程序,并设置与变量
j
相关的观察点。当
j
的值发生变化时,调试器将停止程序。至少您会看到程序的哪一行负责更改,我打赌这不是
assert
。当然不是assert。如前所述,更改j的行是while语句的头(因此
while(!(children->next->root==children->root)){
)也可能不是那一行。因此,运行调试器。因为您的
delete_子树\u aux
是递归的,我认为您在调试器中查看的
j
与您预期的不同。请检查您的
j
holds-4和holds-3是否具有相同的地址。我认为您查看的
delete_子树\u aux
函数,所以实际上没有问题。在递归时,您的函数有多个调用堆栈。最终结果是否错误?