Problems with binary search tree in C

Asked

Viewed 334 times

0

Now reinstating my post more clearly (this is a continuation of my previous question). In the code, I try to create a binary search tree and insert elements into it. They must be saved in .txt. file. As soon as the executor says that . exe has stopped working. When I comment the insert method in main, it runs good. When debugging it accuses Segmentation fault in p->id = 1. I can’t fix it. Follow my code:

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

#define MAX_NOME 50

typedef struct politico{
   int id;
   char* nome;
   char* apelido;
//Partido* partido;
   char* cargo;
   float valorPropinaMensal;
   int quantidadeVezes;

   struct politico* esq;
   struct politico* dir;

}Politico;

   Politico* criarP(int id, char* nomeCompleto, char* apelido, char* cargo, float valor, int qtdDeVezes) {

      Politico* politico = (Politico*)malloc(sizeof(politico));

      politico->id = id;

      politico->nome = malloc(MAX_NOME * sizeof(char));
      strcpy(politico->nome, nomeCompleto);
      politico->apelido = malloc(MAX_NOME * sizeof(char));
      strcpy(politico->apelido, apelido);
      politico->cargo = malloc(MAX_NOME * sizeof(char));
      strcpy(politico->cargo, cargo);
      //no->partido = malloc(MAX_NOME * sizeof(char));
      //strcpy(no->partido, partido);
      politico->valorPropinaMensal = valor;
      politico->quantidadeVezes = qtdDeVezes;
      politico->esq = NULL;
      politico->dir = NULL;

    return politico;
  }

Politico* inserirPoliticos(Politico* raiz, int id, char* nome, char* apelido, char* cargo, float valor, int qtdDeVezes){

   Politico* novo = criarP(id , nome, apelido, cargo, valor, qtdDeVezes);
   if(raiz == NULL) return novo;

   Politico* no = raiz;
   Politico* pai = NULL;
   while(no != NULL){
      pai = no;
      if(novo->id < no->id) no = no->esq;
      else no = no->dir;
  }

   if(pai->id > novo->id) pai->esq = novo;
   else pai->dir = novo;

   return raiz;
}

int main(){
   Politico* p = NULL;

   FILE* pEscrita = fopen("politicos.txt","w");

   p->id = 1;
   p->nome="sdwwfw";
   p->apelido="sdvdsvs";
   p->cargo="asasa";

   p->valorPropinaMensal=22.0;
   p->quantidadeVezes= 2;

   p = inserirPoliticos(p, p->id, p->nome, p->apelido, p->cargo, p->valorPropinaMensal, p->quantidadeVezes);

   fprintf(pEscrita,"%d;%s;%s;%s;%.2f;%d", p->id, p->nome, p->apelido, p->cargo, p->valorPropinaMensal, p->quantidadeVezes);

   fclose(pEscrita);
   return 0;
}
  • When you do that, you isolate the problem. Remove this method and comment on a part of it that thinks that is where the error occurred, if it goes there, will surround the error, if it is not going to change of place where to comment. Of course, you have to have the slightest sense of what you’re doing and not comment on random things. You have to divide and conquer until you reach the point where the error occurs. Of course, you have more professional ways of doing this, but you obviously don’t know how to do it yet.

  • Related question: http://answall.com/q/139820/132 - I hope that the answer I gave you there helped.

1 answer

1

Look at this:

Politico* p = NULL;
p->id = 1;

If p is NULL, it is obvious that p->id = 1; will give a crash.

Let’s see what you try to do:

  1. In the main you try to create (incorrectly) a Politico.
  2. You take all the data from this Politico and passes them one by one to the function inserirPoliticos.
  3. In function inserirPoliticos, the function criarP is called.
  4. In function criarP, a new Politico is mounted again with the same data.

Anyway, you ride the politician, disassemble and reassemble. That’s not very efficient. So there are two possible approaches:

  1. You ride the politician on main and the passage to inserirPoliticos which only inserts a Politico already assembled.

  2. You pass the raw data to the inserirPoliticos and lets inserirPoliticos mount the structure Politico when calling criarP.

I think the first approach is cleaner, by avoiding having to pass a lot of parameters referring to the same thing in several different functions. As such, its function inserirPoliticos gets like this:

Politico* inserirPoliticos(Politico* raiz, Politico *novo) {
    if (raiz == NULL) return novo;

    Politico* no = raiz;
    Politico* pai = NULL;
    while (no != NULL) {
        pai = no;
        if (novo->id < no->id) {
            no = no->esq;
        } else {
            no = no->dir;
        }
    }

    if (pai->id > novo->id) {
        pai->esq = novo;
    } else {
        pai->dir = novo;
    }

    return raiz;
}

And with that, the criarP is used in function main:

int main() {
    Politico *novo = criarP(1, "sdwwfw", "sdvdsvs", "asasa", 22.0, 2);
    Politico *raiz = inserirPoliticos(NULL, novo);

    FILE* pEscrita = fopen("politicos.txt", "w");
    fprintf(pEscrita, "%d;%s;%s;%s;%.2f;%d", p->id, p->nome, p->apelido, p->cargo, p->valorPropinaMensal, p->quantidadeVezes);

    fclose(pEscrita);
    return 0;
}
  • It worked! That’s right. Nice explanation. Thank you.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.