【问题标题】:Insertion error or pointer error in Binary Tree二叉树中的插入错误或指针错误
【发布时间】:2015-11-20 05:26:58
【问题描述】:

当我尝试将一个数字添加到我的二叉树中时,会出现著名的Segmentation Fault

我猜错误是函数inserir_no 中的指针。也许我应该使用指针辅助。

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

/* create a node */

struct no {
   int info;
   struct no *esq;
   struct no *dir;
};

/* function prototypes */

void inserir_no(struct no *arv, int x);

void inserir_no(struct no *arv, int x)
{
    if(arv == NULL) {
        printf("foi");
        arv = (struct no *) calloc(1, sizeof(struct no));
        arv->info = x;
        arv->esq = NULL;
        arv->dir = NULL;
    }
    else if(x < arv->info) {
        inserir_no(arv->esq, x);
    }
    else {
        inserir_no(arv->dir, x);
    }
}

int main(void)
{
    struct no *a;
    int valor;

    a = NULL;

    /* fazer um menu depois */
    scanf("%d", &valor);
    inserir_no(a, valor);

    printf("\nDADOS:\n%d", a->info);
    return 0;
}

【问题讨论】:

  • 你知道如何在你的开发环境中使用调试器吗?这样您就不必猜测错误发生在哪里,并且知道可能可以帮助您找到问题。

标签: c pointers binary-tree


【解决方案1】:

麻烦的是你在插入函数中对arv所做的更改

if(arv == NULL) {
    printf("foi");
    arv = (struct no *) calloc(1, sizeof(struct no));
    arv->info = x;
    arv->esq = NULL;
    arv->dir = NULL;
}

不要更改调用者中传入的指针。函数接收的是存储在调用者变量中的地址的副本,所以当你calloc内存时只有副本被覆盖。

要让函数改变调用者中的变量,让它接受一个指向指针的指针,

void inserir_no(struct no **arv, int x);

并传递指针的地址。

inserir_no(&a, valor);

main,和

else if(x < arv->info) {
    inserir_no(&(*arv)->esq, x);
}
else {
    inserir_no(&(*arv)->dir, x);
}

在递归调用中,以及

if(*arv == NULL) {
    printf("foi");
    *arv = (struct no *) calloc(1, sizeof(struct no));
    (*arv)->info = x;
    (*arv)->esq = NULL;
    (*arv)->dir = NULL;
}

【讨论】:

  • 我有一个问题。当我使用(struct *no arv) 时,我没有收到变量arv 的地址?谢谢!
  • 否,那么您会收到arv 指向的位置的地址。除了struct no** 之外的另一个选项是使用struct no* inserir_no(struct no *arv, int valor) 并让插入返回更新后的节点,然后在main 中设置a = inserir_no(a,valor);,并且您必须在inserir_no 中设置arv-&gt;esq = inserir_no(arv-&gt;esq, valor);arv-&gt;dir 同上) .
【解决方案2】:

呼叫inserir_no(&amp;a, valor);

并将函数的签名更改为inserir_no(struct no **arv , int x)

那么它会因为传递地址而不是指针的值而工作。

*arv 将是 pointer to struct no所以在每个地方都使用它,而不仅仅是 arv

【讨论】:

    【解决方案3】:

    检查main() 中最后一个printf() 之前的a 的值,它仍然是NULL。您需要将 a 的引用传递给函数,以便您分配的内存可以在 main() 中使用。

    在函数inserir_no()中,你需要更新一个指向struct no的指针:

    void inserir_no(struct no **arv, int x)
    

    在函数本身中,您需要更新对arv 的每个引用以进行单个引用:

    if(*arv == NULL) {
        printf("foi");
        *arv = (struct no *) calloc(1, sizeof(struct no));
        (*arv)->info = x;
        //... and the rest, just didn't want to finish it off
    

    然后在main() 中传递结构的地址:

    inserir_no(&a, valor);
    

    另外两个提示:

    1. 你现在有内存泄漏,你需要在离开之前free()你分配的内存
    2. 如果函数在使用前声明,则不需要额外的原型。 (在这种情况下,您在顶部声明它,然后在下面的 main() 中使用它,这样就不需要了)

    【讨论】:

      猜你喜欢
      • 2013-07-15
      • 1970-01-01
      • 1970-01-01
      • 2016-12-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多