nome.exe has stopped working. I can’t fix this

Asked

Viewed 188 times

2

My C code gives a crash displaying following po error:

filename.exe has stopped working

I don’t know how to fix it. Follow the code I’ve already made:

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


typedef struct no{
    int id;
    char* nomeCompleto;
    char* apelido;
    char* partido;
    char* cargo;
    float valorPropina;
    int qtdVezes;
    //Partido* partido;

    struct no* esq;
    struct no* dir;

}No;

No* criarNo(int id, char* nomeCompleto, char* apelido, char* cargo, float valor, int qtdDeVezes){
    No* no = (No*)malloc(sizeof(No));
/*
    printf("id: ");
    scanf("%d", no->id);

    printf("Nome do politico: ");
    gets(no->nomeCompleto);

    printf("Apelido do politico: ");
    gets(no->apelido);

    printf("Cargo do politico: ");
    gets(no->cargo);

    printf("Valor da propina: ");
    scanf("%d", no->valorPropina);

    printf("qtd: ");
    scanf("%d", no->qtdVezes); */
    strcpy(no->nomeCompleto, nomeCompleto);
    strcpy(no->apelido,apelido);
    //p->partido = partido;
    strcpy(no->cargo,cargo);
    no->valorPropina = valor;
    no->qtdVezes = qtdDeVezes;
    no->id = id;

    no->esq = NULL;
    no->dir = NULL;
    return no;
}

No* inserirPolitico(No* raiz, int id, char* nomeCompleto, char* apelido, char* cargo, float valor, int qtdDeVezes){
    No* novo = criarNo(id, nomeCompleto, apelido, cargo, valor, qtdDeVezes);
    if(raiz == NULL) return novo;

    No* no = raiz;
    No* 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;
}

/*
void salvarArquivo(No* no){
    salvarArquivo(no->esq);
    FILE* file;

    file = fopen("ed.txt", "w");
    salvaItem(no, file);

    fclose(file);
    salvarArquivo(no->dir);
}

void salvaItem (No* p, FILE *file){
    if(p->esq)salvaItem(p->esq,file);
    fprintf(file, "%d %s %s %s %d %d\n", p->id, p->nomeCompleto, p->apelido, p->cargo, p->valorPropina, p->qtdVezes);
    if(p->dir)salvaItem(p->dir,file);
}
*/

void imprimirOrdem(No* raiz){
     if(raiz != NULL){
        imprimirOrdem(raiz->esq);

         FILE* file;

        file = fopen("ed.txt", "w");
        //printf("%d - ", raiz->chave);
        fprintf(file, "%d %s %s %s %2f %d\n", raiz->id, raiz->nomeCompleto, raiz->apelido, raiz->cargo, raiz->valorPropina, raiz->qtdVezes);

         fclose(file);

        imprimirOrdem(raiz->dir);
     }
}

int main(){

    No* no =  (No*) malloc(sizeof(No));
    no->nomeCompleto = malloc(sizeof(char));
    no->apelido = malloc(sizeof(char));
    no->cargo = malloc(sizeof(char));



    /*
    printf("id: ");
    scanf("%d", no->id);

    printf("Nome do politico: ");
   gets(no->nomeCompleto);
   // scanf("s", no->nomeCompleto);

    printf("Apelido do politico: ");
    gets(no->apelido);
    //scanf("s", no->apelido);

    printf("Cargo do politico: ");
    gets(no->cargo);
    //scanf("s", no->cargo);
    printf("Valor da propina: ");
    scanf("%d", no->valorPropina);

    printf("qtd: ");
    scanf("%d", no->qtdVezes);

    inserirPolitico(no, no);
    imprimirOrdem(no);
    */
    no->nomeCompleto = "sSASs";
    no->apelido = "scscscs";
    no->cargo ="ddd";
    no->id = 1;
    no->valorPropina = 22.0;
    no->qtdVezes =2;

    inserirPolitico(no, no->id, no->nomeCompleto,  no->apelido, no->cargo, no->valorPropina, no->qtdVezes );
    imprimirOrdem(no);


    return 0;

}
  • You can debug the program to see on which line it gives the error?

  • Put some printf() in the code and find out which line gives the error if you do not know debug kk, but find it there for us! Ah, and describe better what you are trying to do.

  • Breno, welcome to Soft. Go to Ajuda and take the Tour. Edit your question by asking a "clear and objective" question, and if you have an error message in this case, putting it will help....

  • Because any structure that defines the data of a politician, must always have the field valorPropina. :D

  • Here I put the problem more clearly. http://answall.com/questions/139877/problemas-com%C3%81rvore-bin%C3%A1ria-de-search-em-c

1 answer

0

Let’s look at these two lines:

no->nomeCompleto = malloc(sizeof(char));
no->nomeCompleto = "sSASs";

That is, you have allocated a character in memory for the nomeCompleto and placed 5 characters (plus string terminator) in the allocated memory area. As a result, you have written a piece of data larger than the area of memory in which it fits, then invading the underlying area of memory that belongs to something else and corrupting its contents. As this means that your program does not respect the memory limits allocated to it by invading regions of memory that do not belong to you, the result is that error you are having.

To solve this, let’s set a reasonable size for the memory area allocated by each string:

#define MAX_NOME 50
no->nomeCompleto = malloc(MAX_NOME * sizeof(char));
no->apelido = malloc(MAX_NOME * sizeof(char));
no->cargo = malloc(MAX_NOME * sizeof(char));

And never, never, under no circumstances use the function gets. This function is hideous, and is universally and unanimously hated among C programmers. The reason is that it is simply impossible to use this function safely. Every time it’s used, your program already wins a giant hole by which it can catastrophically fail just as your program is failing. There is no correct way to use this function, all forms of use are incorrect.

So instead of using the function gets, use the similar function (but perfectly safe) fgets:

printf("Nome do politico: ");
fgets(no->nomeCompleto, MAX_NOME, stdin);

printf("Apelido do politico: ");
fgets(no->apelido, MAX_NOME, stdin);

printf("Cargo do politico: ");
fgets(no->cargo, MAX_NOME, stdin);

//printf("Partido do politico: ");
//fgets(no->partido, MAX_NOME, stdin);

That being the case, here is its role of creation:

No* criarNo(int id, char* nomeCompleto, char* apelido, char* cargo, /*char *partido,*/ float valor, int qtdDeVezes) {
    No* no = (No*)malloc(sizeof(No));
    no->id = id;
    no->nomeCompleto = malloc(MAX_NOME * sizeof(char));
    strcpy(no->nomeCompleto, nomeCompleto);
    no->apelido = malloc(MAX_NOME * sizeof(char));
    strcpy(no->apelido, apelido);
    no->cargo = malloc(MAX_NOME * sizeof(char));
    strcpy(no->cargo, cargo);
    //no->partido = malloc(MAX_NOME * sizeof(char));
    //strcpy(no->partido, partido);
    no->valorPropina = valor;
    no->qtdVezes = qtdDeVezes;
    no->esq = NULL;
    no->dir = NULL;
    return no;
}

And its function of destruction:

void apagarNo(No *no) {
    free(no->nomeCompleto);
    free(no->apelido);
    free(no->cargo);
    //free(no->partido);
    free(no);
}

There is only one detail in the destruction function: It only destroys the node, but does not remove it from its binary tree. Therefore, if the child nodes have not previously been removed, they will become inaccessible and be dropped off somewhere in memory. If the parent node still points to it after it is removed, then it points to an invalid memory address. So when you call the function apagarNo, first make sure that the node to be deleted is neither child nor parent of any other node, resetting the relevant references to ensure this.

Browser other questions tagged

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