Márcio Gomes
Márcio Gomes

Reputation: 48

Insertion error or pointer error in Binary Tree

When I try to add a number into my binary tree, appears the famous Segmentation Fault.

I guess the error is the pointer in function inserir_no. Maybe I should use a pointer 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;
}

Upvotes: 2

Views: 89

Answers (3)

Mike
Mike

Reputation: 49523

Check the value of a right before the last printf() in main(), it's still NULL. You need to pass a reference of a to the function for the memory you allocated to be use able back in main()

In the function inserir_no(), you need to update to take a pointer to a pointer to a struct no:

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

In the function itself you need to update each reference to arv for a single deference:

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

Then In main() you pass the address of your struct:

inserir_no(&a, valor);

Two other notes for you:

  1. You have a memory leak right now, you need to free() your allocated memory before you leave
  2. You don't need the extra prototype if the function is declared before it's used. (in this case you declared it at the top, then used it below in main() so that's unneeded)

Upvotes: 0

Omkant
Omkant

Reputation: 9234

call as inserir_no(&a, valor);

and change the signature of function to inserir_no(struct no **arv , int x)

then it will work because of passing address rather than value of pointer.

*arv will be the pointer to struct noso use that at every place instead of only arv

Upvotes: 0

Daniel Fischer
Daniel Fischer

Reputation: 183978

The trouble is that the changes you made to arv in the insert function

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

don't change the passed-in pointer in the caller. What the function receives is a copy of the address stored in the variable in the caller, so only the copy is overwritten when you calloc memory.

To make the function change the variable in the caller, make it take a pointer to a pointer,

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

and pass the addresses of the pointers.

inserir_no(&a, valor);

in main, and

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

in the recursive calls, as well as

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

Upvotes: 4

Related Questions