二叉树实现在 C 中给我分段错误

Binary tree implementation gives me segmentation fault in C

我在尝试访问存储在我的 TreeNode 中的数据时遇到分段错误。这是代码:

#include <stdio.h>
#include <stdlib.h>

typedef struct NodeTag{
    int value;
    struct NodeTag *LLink;
    struct NodeTag *RLink;
} TreeNode;

void inOrder(TreeNode * n){
    if(n->LLink != NULL)
        inOrder(n->LLink);
    printf("%d ", n->value);
    if(n->RLink != NULL)
        inOrder(n->RLink);
}

void newNode(TreeNode * n, int v){
    n = malloc(sizeof(TreeNode));
    n->value = v;
    n->LLink = NULL;
    n->RLink = NULL;
}

void addValue(TreeNode * r, int value){

    if(value < r->value){
        if(r->LLink == NULL){
            newNode(r->LLink, value);
        } else {
            addValue(r->LLink, value);
        }
    } else if (value > r->value) {
        if(r->RLink == NULL){
            newNode(r->RLink, value);
        } else {
            addValue(r->RLink, value);
        }
    }
}



int main(){

    TreeNode * root = 0;
    newNode(root, 1);
    printf("%d\n", root->value); //<--This is where I get the fault
    //addValue(root, 3);
    //addValue(root, 10);
    //addValue(root, 2);

    //inOrder(root);

    return 0;
}

如果有人能向我解释为什么会出现此错误,我们将不胜感激。我是一名学习C的学生,我对指针等不太熟悉。

newNode 应 return 指向已分配内存的指针,或者您可以将双指针发送到函数并在那里分配内存。

TreeNode* newNode(int v){
    TreeNode *new_node = malloc(sizeof(TreeNode));

    n->value = v;
    n->LLink = NULL;
    n->RLink = NULL;

    return new_node
}

void newNode(TreeNode ** n, int v){
    *n = malloc(sizeof(TreeNode));
    (*n)->value = v;
    (*n)->LLink = NULL;
    (*n)->RLink = NULL;
}

在 C 中,参数是按值传递的。因此调用 newNode(r->LLink, value) 不会修改 r->LLink.

考虑这个简单的函数:

void Foo(int x)
{
  x = x * 2 ;
}

调用 Foo(n) 会将 n 乘以 2 吗?号

你可能需要这个:

void Foo(int *x)
{
  *x = *x * 2 ;
}

并调用 Foo(&n);

或:

void Foo(int x)
{
  return x * 2 ;
}

并调用 n = Foo(n);

void newNode(TreeNode * n, int v){
    n = malloc(sizeof(TreeNode));
    n->value = v;
    n->LLink = NULL;
    n->RLink = NULL;
}

在此代码中,n 是指向 TreeNode 结构的指针,但如果您将某些内容分配给 n,则在传递指针时,这在函数外部是不可见的按价值。

void writeToA ( int a ) {
    a = 5;
}

int main ( ) {
    int x = 10;
    writeToA(x)
    printf("%d\n", x);
}

这段代码会打印什么?它将打印 10,而不是 5。那是因为 x 的值被传递给函数,而不是对 x 的引用。在函数内更改该值不会更改函数外 x 的值。

指针也是一个值,基本上就是一个int,int值就是一个内存地址:

void writeToPtr1 ( int * a ) {
    int i = 10;
    a = &i; // `a` now points to the memory address of i
}

void writeToPtr2 ( int * a ) {
    *a = 5; // This doesn't change where `a` points to,
    // it writes 5 to the memory address to that `a` points to.   
}

int main ( ) {
    int x = 10;
    int *ptr = &x; // ptr now points to the memory address of x!
    writeToPtr1(ptr);
    // ptr still points to the memory address of x!
    // As not a reference to ptr was passed, the memory
    // address of x was passed to the function!

    writeToPtr2(ptr);
    // ptr still points to the memory address of x!
    // But this memory now has the value 5 and not 10 anymore.
}

您需要return分配的结果:

TreeNode * newNode ( int v ) {
    TreeNode * n = malloc(sizeof(TreeNode));
    n->value = v;
    n->LLink = NULL;
    n->RLink = NULL;
    return n;
}

int main ( ) {
    TreeNode * root = newNode(1);
    printf("%d\n", root->value);
    return 0;
}

或者你需要传递一个指针的引用,然后改变指针指向的值:

 void newNode ( TreeNode ** outNode, int v ) {
    // TreeNode ** is a pointer to a pointer to a TreeNode!
    TreeNode * n = malloc(sizeof(TreeNode));
    n->value = v;
    n->LLink = NULL;
    n->RLink = NULL;
    *outNode = n; // Make the pointer point to `n`
}

int main ( ) {
    TreeNode * root = NULL;
    newNode(&root, 1); // Pass a pointer to root
    printf("%d\n", root->value);
    return 0;
}