我正在尝试切换二叉树子树,但是我得到了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->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
没有必要temp
.实际上,将内存分配给temp
会导致内存泄漏,因为您正在修改存储在temp
中的地址以t
(temp = t
).
我的意思是,在执行temp = t
后,您将丢失指向malloc
地址的指针。这将导致内存泄漏.
Valgrind 肯定会给你丢失的错误。
让我们看看:
void switch(Tree t) {
Tree temp = malloc(sizeof(t));
将缓冲区分配给指针temp
该缓冲区指向使用malloc
分配的未初始化内存。
temp = t;
将指针值分配给temp
t
。 此时您泄漏了分配的内存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;
因此,要切换子项(独立于任何指针为 null),您必须执行以下操作:
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;
}