Ir ao conteúdo
  • Cadastre-se

C Erro com ponteiros/acesso na memória


Riccardoric

Posts recomendados

Salve,

Estou precisando urgentemente resolver este erro... Tenho que entregar o projeto próxima terça-feira, socorro rsrs!

Vamos para o foco do problema, estou fazendo um jogo de dominó em C utilizando obrigatoriamente listas dinamicas e estaticas. Nesse caso, estou utilizando uma pilha estática (montinho das peças), uma lista encadeada (mão do jogador) e uma lista duplamente encadeada (mesa). Fizemos todas as funções necessárias, só que na hora de juntar todas de vez em quando acontece um erro muito estranho e esquisito. Na hora de printar as peças ele começa a printar (me parece ser lixo eletrônico) e de forma infinita. Parece que o encadeamento da lista se rompe e começa a apontar para o lixo, mas a função funciona normalmente em outras questões! Além disso, não sempre que ocorre o erro, é bem eventual mesmo, já tentei encontrar um padrão mas não achei, é totalmente aleatório esse bug.

Imagem do erro:

Vou estar postando os códigos:

 

Loop onde ocorre o print:

Spoiler

void player_choose(tp_hand *player, tp_deck *baralho, tp_jogada *jogo) {
	int certo = 0;
	int esc, iof, exist;
	tp_hand *aux;
	aux = player;
	while (certo == 0) {
		printf("Que operacao deseja realizar?\n1 - Jogar peca\n2 - Cava\n");
		fflush(stdin);
		scanf("%d", &esc);
		if(esc == 2) {
			if(!stack_empty(baralho)) {
				pickupCard(baralho, player);
				printf("Mao do jogador: \n");
				listadin_imprime(player);
				certo = 1;
			} else {
				printf("As pecas acabaram!\n");
				certo = 0;
			}
			
			return;
		} else if(esc == 1) {
			printf("Escolha de 0 a %d qual peca deseja jogar na mesa...\n", listad_size(player) - 1);
			fflush(stdin);
			int pos = 0;
			scanf("%d", &pos);
			if(pos < 0 || pos > listad_size(player) - 1) {
				printf("Peca escolhida nao existe!\n");
				continue;
			}
			printf("Deseja jogar no inicio ou no fim?\n1 - inicio\n2 - fim\n");
			fflush(stdin);
			scanf("%d", &iof);
			//aux = listad_peca_pos(player, esc);
			exist = play_card(player, jogo, pos, iof);
			if(exist == 0) {
				printf("Peca nao inserida\n");
				certo = 0;
			} else if(exist == 1) {
				printf("Peca inserida\n");
				listadin_imprime(player);
				certo = 1;
				return;
			}
		} else {
			continue;
		}
		
	}
}

 

 

Função play_card e pickup card:

 

Spoiler

ret_resp pickupCard(tp_deck *deck_stack, tp_hand *p_hand) {	//Pega uma peça do deck;
	int r_L, r_R;
	
	if (stack_empty(deck_stack)){	//Verifica se o deck esta vazio;
		return 0;	// Retorna '0' se for verdadeiro;
	} else { 	// Caso seja falso, continua;
		
	pop(deck_stack,&r_L, &r_R);	// Retira uma ficha do deck;
	
	listad_insere_peca(&p_hand, r_L, r_R);	// Insere a ficha na mão do jogador;

		return 1;	// Retorna '1' se o processo for bem sucedido.
	}		
}


ret_resp play_card(tp_hand *p_hand, tp_jogada *jogo, int posicao, int inioufim) {
	/*PRECISA SER TESTADO
	  Verificar se a peça encaixa*/
	tp_hand *mao;
	int val_R, val_L;
	mao = listad_peca_pos(p_hand, posicao);
	if(mao == NULL) return 0;
	if(inioufim == 1) {
		if(jogo->ini->v_L == mao->p_L) {
			val_R = mao->p_L;
			val_L = mao->p_R;
		}else if(jogo->ini->v_L == mao->p_R){
			val_R = mao->p_R;
			val_L = mao->p_L;
		} else {
			return 0;
		}
		printf("TESTE\n");
		insere_lista_no_fim(jogo, val_L, val_R);
		remove_lista_valor(&p_hand, mao->p_L, mao->p_R); 
		return 1;
	} else if(inioufim == 2){
		if(jogo->fim->v_R == mao->p_R) {
			val_R = mao->p_L;
			val_L = mao->p_R;
		}else if(jogo->fim->v_L == mao->p_R){
			val_R = mao->p_R;
			val_L = mao->p_L;
		} else {
			return 0;
		}
		printf("TESTE\n");
		insere_lista_no_fim(jogo, val_L, val_R);
		remove_lista_valor(&p_hand, mao->p_L, mao->p_R); 
		return 1;
	} else {
		printf("Posicao invalida\n");
	}
	
	return 1;
}

 

 

Biblioteca da lista dinamica que estou utilizando:

 

Spoiler

#ifndef FILA_D
#define FILA_D
#define NOTSET -1
#include <stdio.h>
#include <stdlib.h>
typedef int tp_peca;
typedef struct tp_listad {
	tp_peca p_L; // Valor esquerdo da peça
	tp_peca p_R; // Valor direita  da peça
	struct tp_listad *next;
}tp_listad;

tp_listad *inicializa_listad() {
	return NULL;
}

tp_listad *listad_aloca(){
	tp_listad *novo;
	novo = (tp_listad *) malloc(sizeof(tp_listad));
	return novo;
}

int listad_vazia(tp_listad *l) {
	if(l == NULL) return 1;
	else return 0;
}

int listad_size(tp_listad *fil) { /*OK*/
	tp_listad *aux;
	aux = fil;
	int count = 0;
	while(aux != NULL) {
		count++;
		aux = aux->next;
	}
	return count;
}

tp_listad *listad_peca_pos(tp_listad *fil, int pos) {
	int tmp = 0;
	tp_listad *aux = fil;
	if(pos >= listad_size(fil)) return NULL;
	while(tmp != pos) {
		if(aux == NULL) return NULL;
		aux = aux->next;
		tmp++;
	}
	if(aux == NULL) return NULL;
	return aux;
}

tp_listad *listad_search_for(tp_listad **fil, tp_peca L, tp_peca R) {
	// Retorna o endereço onde se encontra o valor de e
	// Retorna null caso ele não encontre nada
	tp_listad *aux = *fil;
	while((aux != NULL)) {
		if((aux->p_L == L && aux->p_R == R) || (aux->p_L == R && aux->p_R == L)) {
			return aux;
		}
		aux=aux->next;
	}
	return NULL;
}

tp_listad *listad_search_for_dif(tp_listad **fil, tp_peca L, tp_peca R) {
	// Retorna o endereço onde se encontra o valor de e
	// Retorna null caso ele não encontre nada
	tp_listad *aux = *fil;
	while((aux != NULL)) {
		if(aux->p_L == L && aux->p_R == R) {
			// Encontrou a peça
			return aux;
		}
		aux=aux->next;
	}
	return NULL;
}

int listad_insere_peca(tp_listad **fil, tp_peca L, tp_peca R) {
	tp_listad *aux;
	tp_listad *novo_no;
	novo_no = listad_aloca();
	if(!novo_no) return 0;
	novo_no->p_L = L;
	novo_no->p_R = R;
	novo_no->next = NULL;
	if(listad_vazia(*fil)) {
		*fil = novo_no;
	} else {
		aux = *fil;
		while(aux->next != NULL) {
			aux = aux->next;
		}
		aux->next = novo_no;
	}
	return 1;
}

int remove_lista_valor(tp_listad **l, tp_item L, tp_item R) {
	tp_listad *ant, *atu;
	atu = *l;
	ant = NULL;
	while ((atu!=NULL) && (atu->p_L == L && atu->p_R == R)) {
		ant = atu;
		atu = atu->next;
	}
	if(atu == NULL) return 0;
	if(ant == NULL) {
		*l = atu->next;
	} else {
		ant->next = atu->next;
	}
	free(atu);
	atu = NULL;
	return 1;
}

int listad_remove_peca(tp_listad **fil, tp_listad *endereco_peca) {
	tp_listad *ant, *atu;
	ant = NULL;
	atu = *fil;
	if(endereco_peca == NULL) return 0;
	while(atu != NULL && atu != endereco_peca) {
		ant = atu;
		atu = atu->next;
	}
	if(atu == NULL) {
		//Nao existe o endereço para tal peça
		return 0;
	} else {
		if(ant != NULL) {
			ant->next = atu->next;
		} else {
			*fil = atu->next;
		}
	}
	free(atu);
	atu = NULL;
	return 1;
}

void listadin_imprime(tp_listad *fil){
	tp_listad *aut;
	aut = fil;
	while(aut != NULL) {
		printf("[%d|%d]\t", aut->p_L, aut->p_R);
		aut = aut->next;
	}
	printf("\n");
}

int listad_soma(tp_listad *fil){ /*OK*/
	tp_listad *aux;
	int soma = 0;
	aux = fil;
	while(aux != NULL) {
		soma += aux->p_L;
		soma += aux->p_R;
		aux = aux->next;
	}
	return soma;
}



#endif

 

 

O erro ocorre na hora de printar as peças do jogador e de forma aleatoria.

Quem quiser baixar o projeto para tentar rodar:

GitHub - RiccardoCafa - Domino-s-Pizza

 

Alguém me ajuda socorro!

Link para o comentário
Compartilhar em outros sites

@Riccardoric Olá. Me pareceu bem interessante seu projeto. 

Só q já vou direto a um ponto q vejo ser interessante alterar.

Você por várias vezes está fazendo uso do comando fflush(stdin); para limpar o stdin.

Cara, esse comando não é nada recomendável e inclusive a gente aqui evita o uso do mesmo.

Vou passar duas funções q você pode usar em seu código q efetuam a limpeza do stdin d maneira eficaz:

void limpa_linha() {
    scanf("%*[^\n]");
    scanf("%*c");
}
void fflush_stdin() {
    int ch;
    while ((ch = getchar()) != '\n' && ch != EOF);
}

Pode optar pela qual achar mais conveniente usar, mas evite o uso desse comando fflush(stdin);

Eu mesmo usava esse comando e aprendi melhor aqui mesmo no fórum a respeito desse comando e por isso deixei d usá-lo 

Quanto ao problema mencionado q está dando é preciso analisar com bastante calma o código todo p daí dar uma resposta adequada

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