Ir ao conteúdo

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


Ir à solução Resolvido por kgin,

Posts recomendados

Postado

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
  • Solução
Postado
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
Postado
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
Postado
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

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...