Ir ao conteúdo

Posts recomendados

Postado

Olá sou iniciante em C estou tendo problemas ao passa matrizes como ponteiro, No meu code Quando o programa ler a variável temp logo em seguida aparece um erro no meu terminal "Falha de segmentação (imagem do núcleo gravada)", Eu pesquisei muito sobre o assunto e mesmo assim não conseguir enxergar o Erro. Alguém poder me livrar dessa dor de cabeça? Desde já Obrigado :)

 

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

// Jogo da Velha

void saida(int PL[][3], int TabNum[][3]);
	void entrada(int **PL, int Player, int TabNum[][3]);

int main(){
	printf("________________________________________________________________\n");

	 int PLog[3][3] = {}; // Esta tabelá só poder armazenar 0, 1 , 3 em seus elementos
	 int NumDisplay[3][3] = { 1, 2, 3,
							  4, 5, 6,
							  7, 8, 9}; // Esta Tabela e usada para indicar as posição da Tabela PLog[3][3]

	int Player = 2; // 1 == X || 2 == O, Esta varivel e usada para indicar qual e o jogador da bolinha ou do X

entrada(PLog, Player, NumDisplay); /* Esta função inserir o valor da varivel "Player" na tabela "PLog[3][3]" na posição de
                            acordo com os valores dos elementos da tabela "NumDisplay[3][3]", Que e escolhida inserindo valor da
                            variavel "temp" depois e verificada por uma condicional "if(temp == TabNum[x][z])" dentro de uma estrutura For */

	saida(PLog, NumDisplay); // imprimir elementos do jogo da velha


	return 0;

}

// Imprimir Jogo da Velha
void saida(int PL[][3], int TabNum[][3]){
	for(int x = 0; x < 3; x++){
			for(int z = 0; z < 3; z++){

				switch(PL[x][z]){
						case 1:
								printf(" X ");
							break;
						case 2:
							printf(" X ");
							break;
						default:
							printf(" %i ",TabNum[x][z]);
					}
			}
		printf("\n");
	}
}

// Inserir a pocição do X que e (Player==1) (Player==2)
void entrada(int **PL, int Player, int TabNum[][3]){
    int temp = 0;

	scanf("%d", &temp);

        	for(int x = 0; x < 3; x++){
                for(int z = 0; z < 3; z++){
                    if(temp == TabNum[x][z]){
                        PL[x][z] = Player;
                    }
                }
            }
}

 

  • Obrigado 1
Postado

@Leirbag System NRx    para usar matriz de ponteiro você precisa alocar espaço para ela usando o comando  malloc   , mas essa matriz  **PL ,  na função entrada não modifica o conteúdo da matriz PLog , e depois você envia essa matriz para a função saida , ela não terá os números  da matriz PL , então para isso seria melhor usar matriz normal mesmo , então seu código modificado seria assim  :

#include <stdlib.h>
#include <stdio.h>
// Jogo da Velha
void saida(int PL[3][3], int TabNum[3][3]);
void entrada(int **PL, int Player, int TabNum[3][3]);
int i,j;
int PLog[3][3]; // Esta tabelá só poder armazenar 0, 1 , 3 em seus elementos
int main(){
    printf("________________________________________________________________\n");
//    int PLog[3][3] = {}; // Esta tabelá só poder armazenar 0, 1 , 3 em seus elementos
    int NumDisplay[3][3] = { {1, 2, 3},
                             {4, 5, 6},
                             {7, 8, 9}
                            }; // Esta Tabela e usada para indicar as posição da Tabela PLog[3][3]
    for(i=0;i<3;i++){
        for(j=0;j<3;j++){
            printf("%d ",NumDisplay[i][j]);
        }
        printf("\n");
    }
    int Player = 2; // 1 == X || 2 == O, Esta varivel e usada para indicar qual e o jogador da bolinha ou do X
    entrada(PLog, Player, NumDisplay); /* Esta função inserir o valor da varivel "Player" na tabela "PLog[3][3]" na posição de
                            acordo com os valores dos elementos da tabela "NumDisplay[3][3]", Que e escolhida inserindo valor da
                            variavel "temp" depois e verificada por uma condicional "if(temp == TabNum[x][z])" dentro de uma estrutura For */
    saida(PLog, NumDisplay); // imprimir elementos do jogo da velha
    printf("\n\n");
     for(i=0;i<3;i++){
        for(j=0;j<3;j++){
            printf("%d ",PLog[i][j]);
        }
        printf("\n");
    }
	return 0;
}
// Imprimir Jogo da Velha
void saida(int PL[3][3], int TabNum[3][3]){
	for(int x=0; x<3; x++){
        for(int z=0; z<3; z++){
            switch(PL[x][z]){
            case 1:
                printf(" X ");
                break;
            case 2:
                printf(" O ");
                break;
            default:
                printf(" %i ",TabNum[x][z]);
            }
        }
        printf("\n");
    }
}
// Inserir a pocição do X que e (Player==1) (Player==2)
void entrada(int **PL, int Player, int TabNum[3][3]){
    int temp = 0;
    PL = (int**)malloc(3*sizeof(int));
    scanf("%d", &temp);
    for(int x=0; x<3; x++){
        PL[x]=(int*)malloc(3*sizeof(int));
        for(int z=0; z<3; z++){
            if(temp == TabNum[x][z]){
                PL[x][z] = Player;
            }
            else
                PL[x][z] = 0;
            printf("%d ",PL[x][z]);
        }
        printf("\n");
    }
    printf("\n\n");
}

 

Postado

Pra você entender primeiro vamos voltar aos vetores. Isso lida com a diferença entre um vetor e um ponteiro.

 

Quando você criar um vetor:

int vetor[3];

Se usar o nome vetor sem os colchetes posteriormente no programa para armazenar num ponteiro, na prática o que é retornado é a referência da primeira casa do vetor, ou seja é o mesmo que fazer &vetor[0].

 

Então:

int vetor[3];
int *ponteiro;

//Fazer isso:
ponteiro = vetor;

//É o mesmo que fazer isso:
ponteiro = &vetor[0];

Resultando em ambos os casos que o ponteiro aponta para a primeira casa do vetor (e não para o vetor inteiro).

 

Podemos então fazer aritmética de ponteiros, ou notação de vetores, para apontar para as demais casas do vetor.

//Por exemplo poderiamos acessar a terceira casa do vetor fazendo:

*(ponteiro + 2)

//Ou:

ponteiro[2]

Poderíamos acessar essa casa da mesma maneira diretamente no vetor fazendo vetor[2] (ou *(vetor + 2)), mas a diferença do ponteiro para o vetor é que o vetor contém a informação sobre o número de casas que ele contém, nesse caso ele é composto por 3 inteiros, mas esse ponteiro contém informação apenas sobre a primeira casa para onde ele aponta. Se usar a palavra chave sizeof para checar o tamanho verá que sizeof(vetor) é diferente de sizeof(ponteiro).

 

 

Agora no caso da matriz:

int matriz[3][3];

Seguindo a mesma lógica dada para os vetores, ao usar o nome matriz será obtida a referência para &matriz[0], ou seja a referência da primeira linha inteira da matriz, mas é um vetor inteiro de 3 posições, logo fazer essa atribuição num ponteiro comum não seria compatível:

int *ponteiro;

ponteiro = &matriz[0]; //ERRO

Pois esse ponteiro só pode apontar para 1 único inteiro, mas está tentando guardar nele uma referência para um vetor com 3 inteiros.

 

Nesse caso precisamos introduzir o conceito de um ponteiro que aponta para um vetor/array, para poder armazenar esta referência, cuja notação é (*ponteiro)[n], ou seja trata-se de um ponteiro que aponta para um array de comprimento n.

 

Então nesse caso o código correto ficaria assim:

int matriz[3][3];
int (*ponteiro)[3];

ponteiro = &matriz[0]; //CORRETO

//Que é igual a:
ponteiro = matriz;

Logo, é necessário usar um ponteiro para um array no parâmetro da função, mas já que vai ter que colocar o número de colunas de qualquer maneira pode usar a notação de matriz flexível que já está usando em outras partes do código ponteiro[][3], é só uma questão de preferência.

 

 

O seu engano foi usar um ponteiro para ponteiro (int **ponteiro) como parâmetro da função, e isto trata-se de um ponteiro que aponta para outra variável do tipo ponteiro, e não serve para apontar para um vetor, não contém a informação do comprimento do vetor logo são incompatíveis. E o que ocorreu no seu programa foi uma conversão forçada de um tipo o para outro, mas quando o programa tenta percorrer as posições da matriz nesse ponteiro eventualmente acaba tentando acessar uma posição da memória que não foi alocada e causa o crash do programa.

 

OBS: Também não deve confundir um ponteiro para um vetor (*ponteiro)[n] , com um vetor de ponteiros *vponteiros[n], pois nesse segundo está sendo criado um vetor com n ponteiros comuns.

 

 

 

 

Uma alternativa para não fixar o tamanho da matriz nos parâmetros da função é usar uma matriz de comprimento variável assim:

int func(int linhas, int colunas, int matriz[linhas][colunas]);
  
//ou para uma matriz quadrada:
  
int func(int n, int matriz[n][n]);

Nesse caso é importante que os parâmetros estejam na ordem correta, ou seja linhas e colunas tem que vir antes de matriz pois esta depende de que as variáveis já tenham sido declaradas no escopo da função, e já tenham recebido valores que definirão seu tamanho.

  • Curtir 2
  • Obrigado 1
Postado

Perceba aritmética na notação de vetor e migre para a de ponteiro. Como resultado um código mais homogêneo isso facilitará nas futuras depurações. 

  • Curtir 1
  • Obrigado 1

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