Ir ao conteúdo
  • Cadastre-se

C Por que esse código não está rodando apropriadamente?


Nobara
Ir à solução Resolvido por kgin,

Posts recomendados

Estou tentando fazer uma pilha alocada dinamicamente em C mas ele não está funcionando direito, não consigo enxergar onde está o erro. Não julgue muito meu código, ainda sou iniciante.

 

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

 

typedef struct elemento{
    int valor;
    struct elemento *anterior;
}Elemento;

 

typedef struct pilha{
    Elemento *topo;
}Pilha

 

Pilha* criaPilha ();

 

void liberaPilha (Pilha* p);

 

int tamanho (Pilha* p);

 

int empilha (Pilha* p, int v);

 

int desempilha (Pilha* p);

 

int estahvazia (Pilha* p);

 

int main(){
    Pilha *a;
    a = criaPilha();

     int x = 1, y;

 

    do{
        printf("---------------------------------\n");
        printf("          ~~~~MENU~~~~\n");
        printf("1. Inserir um elemento na pilha\n");
        printf("2. Retirar um elemento da pilha\n");
        printf("3. Tamanho da pilha\n");
        printf("0. Sair\n");
        printf("Opcao: ");
        scanf("%d", &x);
        printf("---------------------------------\n");


        switch(x){
        case 1:
            printf("Elemento que deseja inserir: ");
            scanf("%d", &y);
            empilha(a, y);
            printf("Elemento inserido!!\n\n");
            break;


        case 2:
            if(estahvazia(a) == 1)
                printf("Pilha vazia :(\n");
            else{
                desempilha(a);
                printf("Primeiro elemento da pilha retirado!!\n\n");
            }
            break;


        case 3:
            printf("Quantidade de elementos na pilha: %d\n\n", tamanho(a));
            break;


        default:
            printf("Opcao invalida\n");
            break;
        }
    }while(x != 0);

 

    liberaPilha(a);
    return 0;
}

 

Pilha* criaPilha (){
    Pilha *p;
    p = (Pilha*) malloc(sizeof(Pilha));
    if(p == NULL){
        printf("Erro: memoria insuficiente\n");
        system("pause");
        exit(1);
    }
    p -> topo == NULL;
    return p;
}

 

void liberaPilha (Pilha* p){
    while(estahvazia(p) != 1){
        Elemento *aux;
        aux = p -> topo;
        p -> topo = p -> topo -> anterior;
        free(aux);
    }
    free(p);
}

 

int tamanho (Pilha* p){
    int soma = 0;
    Elemento *aux;
    aux = p -> topo;
    while(aux != NULL){
        soma++;
        aux = aux -> anterior;
    }
    return soma;
}

 

int estahvazia (Pilha* p){
    if(p == NULL)
        return 1;
    if(p -> topo == NULL)
        return 1;
    else
        return 0;
}

 

int empilha (Pilha* p, int v){
    Elemento *aux;
    aux -> valor = v;
    aux -> anterior = p -> topo;
    p -> topo = aux;
    return 1;
}

 

int desempilha (Pilha* p){
    if(estahvazia(p) == 1)
        return 0;
    Elemento *aux;
    aux = p -> topo;
    p -> topo = aux -> anterior;
    free(aux);
    return 1;
}>
 

  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

  • Solução
1 hora atrás, Nobara disse:

Estou tentando fazer uma pilha alocada dinamicamente em C mas ele não está funcionando direito, não consigo enxergar onde está o erro.

tem muitos, muitos erros.

Mas o principal é aqui

1 hora atrás, Nobara disse:

int empilha (Pilha* p, int v){
    Elemento *aux;
    aux -> valor = v;
    aux -> anterior = p -> topo;
    p -> topo = aux;
    return 1;
}

Você não reservou a memória para o próximo elemento na pilha.

  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

4 horas atrás, kgin disse:

tem muitos, muitos erros.

Mas o principal é aqui

Você não reservou a memória para o próximo elemento na pilha.

Funcionou! Que outros erros você está mencionando? 

Mesmo o código funcionando, queria saber para melhorar.

 

4 horas atrás, devair1010 disse:

@Nobara      Qual erro que tem ?  , 

Depois que o usuário seleciona uma das opções do menu e a função é feita, o programa encerra.

  • Curtir 1
  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

2 horas atrás, Nobara disse:

Funcionou! Que outros erros você está mencionando? 

Um deles é esse aqui

2 horas atrás, Nobara disse:

Depois que o usuário seleciona uma das opções do menu e a função é feita, o programa encerra.

Você errou quando criou a função criaPilha() na inicialização da pilha.

Aqui o erro

9 horas atrás, Nobara disse:

p -> topo == NULL;

E quando você utiliza a função tamanho() ela vai desempilhar e utilizar esse valor, mas o valor e desconhecido pelo fato que ele não foi inicializado na função criaPilha().

 

Aqui a saída do gdb mostrando o erro

1758928507_Capturadetela_2022-04-14_19-33-52.thumb.png.c569b9e8a35a1aa3d11ad4ed81cca168.pngVeja que no endereço anterior ele era um endereço valido, mas no ultimo endereço ele aponta para lugar nenhum fazendo o programa ter SEGV e abortando.

 

Outra coisa que eu acho que você deveria fazer e deixa o programa principal lidar com um erro ao invés de abortar o programa.

9 horas atrás, Nobara disse:

Pilha* criaPilha (){
    Pilha *p;
    p = (Pilha*) malloc(sizeof(Pilha));
    if(p == NULL){
        printf("Erro: memoria insuficiente\n");
        system("pause");
        exit(1);
    }
    p -> topo == NULL;
    return p;
}

você deveria só fazer algo assim.

struct st_pilha
*pilha_cria(void)
{
    struct st_pilha *pilha = malloc(sizeof(*pilha));
    if (pilha != NULL) {
        pilha->tamanho = 0;
        pilha->pilha = NULL;
        return(pilha);
    }
    return(NULL);
}

Só verificando o erro na função principal.

 

Aqui o resto do algoritmo de exemplo

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

struct st_lista
{
    int valor;
    struct st_lista *anterior;
};

struct st_pilha
{
    struct st_lista *pilha;
    int tamanho;
};

void
pilha_destroi(struct st_pilha **pilha);

struct st_pilha
*pilha_cria(void);

int
pilha_empilha(struct st_pilha *pilha, int valor);

int
pilha_desempilha(struct st_pilha *pilha);

int
pilha_tamanho(struct st_pilha *pilha);

int main(void)
{
    struct st_pilha *pilha = pilha_cria();
    if (pilha == NULL) {
        printf("deu problema!\n");
        exit(EXIT_FAILURE);
    }
    pilha_empilha(pilha, 10);
    pilha_empilha(pilha, 11);
    pilha_empilha(pilha, 12);
    pilha_empilha(pilha, 13);
    printf("O tamanho da pilha e %i\n", pilha_tamanho(pilha));
    printf("Valor na pilha %i\n", pilha_desempilha(pilha));
    printf("Valor na pilha %i\n", pilha_desempilha(pilha));
    printf("Valor na pilha %i\n", pilha_desempilha(pilha));
    printf("Valor na pilha %i\n", pilha_desempilha(pilha));
    printf("O tamanho da pilha agora e %i\n", pilha_tamanho(pilha));
    pilha_destroi(&pilha);
    getchar();
    return(0);
}

void
pilha_destroi(struct st_pilha **pilha)
{
    if (*pilha != NULL) {
        while ((*pilha)->pilha != NULL) {
            struct st_lista *tmp = (*pilha)->pilha->anterior;
            free((*pilha)->pilha);
            (*pilha)->pilha = tmp;
        }
        (*pilha)->pilha = NULL;
        free(*pilha);
    }
    *pilha = NULL;
}

struct st_pilha
*pilha_cria(void)
{
    struct st_pilha *pilha = malloc(sizeof(*pilha));
    if (pilha != NULL) {
        pilha->tamanho = 0;
        pilha->pilha = NULL;
        return(pilha);
    }
    return(NULL);
}

int
pilha_empilha(struct st_pilha *pilha, int valor)
{
    struct st_lista *no = malloc(sizeof(*no));
    if (no != NULL) {
        no->valor = valor;
        no->anterior = pilha->pilha;
        pilha->pilha = no;
        pilha->tamanho++;
        return(1);
    }
    return(0);
}

int
pilha_desempilha(struct st_pilha *pilha)
{
    if (pilha->pilha != NULL) {
        int valor = pilha->pilha->valor;
        struct st_lista *tmp = pilha->pilha->anterior;
        free(pilha->pilha);
        pilha->pilha = tmp;
        pilha->tamanho--;
        return(valor);
    }
    return(0);
}

int
pilha_tamanho(struct st_pilha *pilha)
{
    return(pilha->tamanho);
}

 

Recomendo ler esse blog para entender como identificar os erros.

https://sergioprado.org/identificando-problemas-de-acesso-memoria-com-o-addresssanitizer/

  • Obrigado 2
Link para o comentário
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...

Ebook grátis: Aprenda a ler resistores e capacitores!

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!