2012-11-26 4 views
2

이진 트리에 숫자를 추가하려고하면 유명한 세그먼트 화 오류이 표시됩니다.이진 트리의 삽입 오류 또는 포인터 오류

오류가 포인터 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; 
} 
+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; 
} 

가 변경되지 않습니다 전달 된 발신자에 대한 포인터입니다. 함수가받는 것은 호출자의 변수에 저장된 주소의 사본이므로 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; 
} 
+0

질문이 있습니다. 내가'(struct * no arv)'를 사용할 때 변수 arv의 주소를받지 못했습니까? 고맙습니다! –

+0

아니요, 'arv'가 가리키는 위치의 주소를받습니다. 'struct no ** inserir_no (struct no * arv, int valor)'를 가지고 삽입 된 노드를 반환하고, 그 다음에 a = inserir_no (a, valor); 'main'을 사용하면'inserir_no'에'arv-> esq = inserir_no (arv-> esq, valor);'('arv-> dir'과 동등)을 설정해야합니다. –

0

는 여전히 NULL의 오른쪽 main()의 마지막 printf() 전에 a의 값을 확인하십시오. 당신은 당신이 기능 inserir_no()에서 다시 main()

에서 수 사용되는 할당 된 메모리 함수에 a의 참조를 전달해야합니다, 당신은 struct no에 대한 포인터에 대한 포인터를 취할 업데이트해야합니다

기능이 하나의 존중에 대한 arv에 대한 각 참조 업데이트해야합니다 자체에서
void inserir_no(struct no **arv, int x) 

: main()에서 다음

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 

당신 당신의 구조체의 주소를 전달합니다

inserir_no(&a, valor); 

다른 두 음을 당신을 위해 :

  1. 을 당신은 당신이 돈
  2. 을 떠나기 전에 당신이 당신의 할당 된 메모리를 free() 필요, 지금 메모리 누수가 ' 함수가 사용되기 전에 선언 된 경우 추가 프로토 타입이 필요합니다.(이 경우 당신은 그 main() 아래 그것을 사용, 상단을 선언 그래서 불필요한이다) inserir_no(&a, valor);

0

호출 후 작동합니다 inserir_no(struct no **arv , int x)

에 함수의 서명을 변경 포인터의 가치 라기보다는 주소를 전달하기 때문입니다. 당신이 당신의 개발 환경에서 디버거를 사용하는 방법을 알고 계십니까

*arv이 (가) pointer to struct no 그래서 모든 장소에서 그것을 사용하는 대신 단지 arv