2012-11-26 58 views
2

當我嘗試向我的二叉樹中添加一個數字時,出現着名的分段錯誤二叉樹中插入錯誤或指針錯誤

我想這個錯誤是函數inserir_no中的指針。也許我應該使用指針aux。

#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; 
} 
+0

你知道如何使用調試器在開發環境?因此,您不必猜測錯誤發生的位置,並知道*可能會*幫助您找到問題。 – dmckee

回答

4

麻煩的是,改變你在插入功能arv作出

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

不改變傳入的調用者的指針。該功能收到的是存儲在調用者變量中的地址的副本,因此只有當您的內存被複制時纔會覆蓋該副本。

爲了使功能改變變量在調用者,使其採取一個指針的指針,

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; 
} 
+0

我有一個問題。當我使用'(struct * no arv)'我沒有收到變量arv的地址?謝謝! –

+0

不,那麼你會收到'arv'指向的地址。除了'struct no **'之外的另一個選項是'struct no * inserir_no(struct no * arv,int valor)'並且插入返回更新的節點,然後'a = inserir_no(a,valor);'in 'main',你必須在'inserir_no'中設置'arv-> esq = inserir_no(arv-> esq,valor);'(同樣適用於'arv-> dir')。 –

0

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()所以這是不需要的)
0

電話爲inserir_no(&a, valor);

和功能的簽名更改爲inserir_no(struct no **arv , int x)

那麼它會工作因爲傳遞地址而不是指針的值。

*arv將是pointer to struct no所以使用,在每一個地方,而不是隻arv