【问题标题】:Switching binary tree subtrees SIGSEV切换二叉树子树 SIGSEGV
【发布时间】:2021-03-20 11:12:13
【问题描述】:

我正在尝试切换二叉树子树,但是我得到了 SIGSEV,但我不知道如何解决这个问题

我的树结构:

typedef struct Tree_node_ Tree_node;
typedef Tree_node* Tree;

struct Tree_node_
{
    int value;
    Tree left;
    Tree right;
};

切换子树代码:

void switch(Tree t) {
    Tree temp = malloc(sizeof(t));
    temp = t;
    t = t->left;
    temp->left = t->right;
    t->right = temp;
}

当我尝试阅读 t->right 时发生错误

【问题讨论】:

  • temp = t; 这个分配覆盖了malloc
  • @kiranBiradar 我已经尝试分配新的温度,通过给它赋值,左,右 t,但仍然没有运气。
  • temp 应该只是一个单一的指针:temp = t->left; t->left = t->right; t->right = temp; 当然,它已经只是一个单一的指针,但是您已经与typedef 混淆了。故事的寓意:不要 typedef 指针。

标签: c pointers segmentation-fault binary-tree


【解决方案1】:

temp->left = t->right

分段错误的原因:在这里您将t->left->right 分配给temp->left,因为t->right = t->left->right (t = t->left)。

解决方案
temp = t->left;
t->left = t->right;
t->right = temp

不需要 malloc temp。事实上,分配内存给temp会导致内存泄漏,因为你正在将temp中存储的地址修改为t (temp = t)。
我的意思是,在执行 temp = t 之后,您将丢失指向 malloc'ed 地址的指针。这会导致内存泄漏。
Valgrind 会给你肯定丢失错误。

【讨论】:

  • 嗯,我也想切换值,这个算法不会抛出错误,但它不是我需要的
  • 几乎是正确答案,但最后一行当然应该是t->right = temp;
  • @printf 感谢您指出错误。修好了。
【解决方案2】:

让我们看看:

void switch(Tree t) {
    Tree temp = malloc(sizeof(t));

您为temp 指针分配一个缓冲区,该缓冲区指向使用malloc 分配的未初始化内存。

    temp = t;

您将t 的指针值分配给temp。此时您泄漏了使用malloc() 分配的内存,从此时起,该内存没有指向它的引用。

    t = t->left;

您将t 的值更改为指向它的左孩子,但没有上下文可以知道t 的左孩子是否存在(可能是NULL

    temp->left = t->right;

您现在拥有原始t 节点的两个子节点指向同一个right 子节点(而原始节点仍由temp 指向)

    t->right = temp;
}

现在t->right 指向它的父节点。

首先,没有必要使用malloc(),因为您应该交换节点t 的子节点,您没有向树中插入新节点。其次,要交换两个变量的值(无论是指针、数字还是其他),有一个简单的代码可以让您这样做,即:

    Type temp = a;
    a = b;
    b = temp;

所以,要切换孩子(独立于任何指针为空),您必须这样做:

void switch(Tree t) {
    Tree temp = t->left;
    t->left = t->right;
    t->right = temp;
}

没有 malloc,没有更多的临时变量等。即使子指针是 NULL,此代码也有效。如果您还想检查t 是否不为空,则:

#include <stdlib.h>  /* for EXIT_FAILURE */

void switch(Tree t) {
    if (t == NULL) {
        printf("Illegal parameter NULL passed to switch()");
        exit(EXIT_FAILURE);
    }
    Tree temp = t->left;
    t->left = t->right;
    t->right = temp;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-01-07
    • 2012-02-28
    • 1970-01-01
    • 2015-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多