Ir ao conteúdo
  • Cadastre-se

C Erro ao passa matriz como ponteiro (Falha de segmentação)


Posts recomendados

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
Link para o comentário
Compartilhar em outros sites

@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");
}

 

Link para o comentário
Compartilhar em outros sites

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