nome.exe has stopped working. I can not fix this [duplicate]

2

My code in C gives a crash displaying the following error:

  

name.exe stopped working

I do not know how to fix this. Here is the code I've already done:

#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;

}
    
asked by anonymous 10.07.2016 / 04:34

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 nomeCompleto and put 5 characters (plus the string terminator) into the allocated memory area. As a result, you have written a datum larger than the area of memory it fits into, invading then the underlying memory area that belongs to something else and corrupting its contents. As this means that your program does not respect the memory limits it allocates, invading regions of memory that do not belong to it, the result is this error you are having.

To solve this, let's define 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 gets function. This function is awful, and is universally and universally hated among programmers C. The reason is that it is simply impossible to use this function in a secure way. Whenever it is used, your program already earns itself a huge gulf by which it can fail catastrophically the same way your program is failing. There is no correct way to use this function, all forms of use of it are incorrect.

So, instead of using the gets function, use the similar (but perfectly safe) function 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);

So, here's your creative function:

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 destructive function:

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 been previously removed, they will be inaccessible and will be dropped somewhere in the memory. If the parent node still continues to point to it after it is removed, then it points to an invalid memory address. So, when you call the apagarNo function, first make sure that the node to be deleted is not a child or parent of any other node, by redefining the relevant references to ensure this.

    
10.07.2016 / 07:30