Ir ao conteúdo
  • Cadastre-se
Vitor Avancini

Acessar matriz dentro de uma função

Recommended Posts

Como comparar uma determinada posição de uma matriz através de colchetes sendo que passei como ponteiro de ponteiro (int **matriz)

Main:

while (qtdRainhas < n)
            {
                printf("\nInsira a linha: ");
                scanf("%i", &ri);
	            printf("\nInsira a coluna: ");
	            scanf("%i", &rj);
	            verifica = verificaConflitos(ri-1, rj-1, tabuleiro, n);
                printf("verificou");
	            if (verifica == 0)
	            {
	                printf("\nentrou if\n");
	                tabuleiro[ri][rj] = 1;
	                printf("Inseriu rainha %i" , i);
	                qtdRainhas++;
	            }
                else
                    printf("\nPosicao invalida, insira novamente!");
            }
            printf("\n");
	        Imprimir(tabuleiro, n);

.h

/**Imprime todas as posições do tabuleiro*/
void Imprimir(int **tabuleiro, int n);
/**VERIFICA SE É POSSÍVEL POSICIONAR A RAINHA EM matriz(ri, rj).
RETORNA 1 SE NÃO É POSSÍVEL E 0 SE FOR POSSÍVEL*/
int verificaConflitos (int ri, int rj, int **tabuleiro , int n);

funcoes.c

int verificaConflitos (int ri, int rj, int **tabuleiro, int n)
{
    int i, i1, i2, j, j1, j2;
    int teste = 0;

    i1 = ri;
    i2 = ri;
    j1 = rj;
    j2 = rj;
    printf("\nentrou verificaConflito");
    /**TESTA SE EXISTE ALGUMA NA MESMA LINHA OU COLUNA*/
    for (i = 0; i < n; i++)
    {
        printf("\nentrou for");
        if (tabuleiro[ri][i] == 1 || tabuleiro[i][rj] == 1)//o erro acontece aqui!
        {
            teste = 1;
            printf("\nentrou if");
            break;
        }
        printf("\nsaiu for");
    }

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Quando chega na parte que comentei que da erro, o programa fecha. Gostaria de entender o erro e saber qual a maneira correta. 

adicionado 2 minutos depois

A execução do programa fica assim: Capturar.PNG

Compartilhar este post


Link para o post
Compartilhar em outros sites
47 minutos atrás, Vitor Avancini disse:

int verificaConflitos (int ri, int rj, int **tabuleiro, int n) { 

... if (tabuleiro[ri][i] == 1 || tabuleiro[i][rj] == 1)//o erro acontece aqui! 

}

no cabeçario da função o parâmetro é um ponteiro-para-ponteiro;

Na comparação você trata o objeto como sendo um Array Bidimensional #Erro

A solução mais prática ao meu pensar é:

Mudar o cabeçario para .: 

int verificaConflitos (int ri, int rj, int tabuleiro[ri][rj], int n)

Ok:thumbsup:

Compartilhar este post


Link para o post
Compartilhar em outros sites

Não existe isso, internamente, um arranjo bidimensional é um ponteiro de ponteiro.

Me manda como você alocou esse tabuleiro, eu testei sua função aqui e deu certo, eu aloquei o tabuleiro e testei valores aleatorios e rodou normal.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Código completo:

main.c:

#include<stdio.h>
#include "cabecalho.h"

void main ()
{
    int i, j, ri, rj;
    int teste = 1;
    int **tabuleiro;
    int **matrizAdj;
    int n, qtdRainhas = 0;
    int p1, p2, op;
    int verifica;

   	printf("Insira o tamanho do tabuleiro e a quantidade de rainhas (N): ");
    scanf("%i", &n);
    construirMatriz(tabuleiro, n);
    printf("\nConstruiu tabuleiro\n");
    printf ("\nInsira o metodo de insercao: ");
    printf("\n1 - Manual");
    printf("\n2 - XGH");
    printf("\n3 - Heurística");
    printf("\n");
	scanf ("%i", &op);

	switch (op)
	{
	    case 1:
	        while (qtdRainhas < n)
            {
                printf("\nInsira a linha: ");
                scanf("%i", &ri);
	            printf("\nInsira a coluna: ");
	            scanf("%i", &rj);
	            verifica = verificaConflitos(ri-1, rj-1, tabuleiro, n);
                printf("verificou");
	            if (verifica == 0)
	            {
	                printf("\nentrou if\n");
	                tabuleiro[ri][rj] = 1;
	                printf("Inseriu rainha %i" , i);
	                qtdRainhas++;
	            }
                else
                    printf("\nPosicao invalida, insira novamente!");
            }
            printf("\n");
	        Imprimir(tabuleiro, n);
	        break;
	   case 2:
	       while(qtdRainhas < n)
           {
                for (i = 0; i < n; i++)
                {
                     for(j = 0; j < n; j++)
                     {
                         if (!verificaConflitos(i-1, j-1, tabuleiro, n))
                        {
                            tabuleiro [i] [j] = 1;
                            printf("\nInseriu rainha");
                            qtdRainhas++;
                        }
                     }
                }
           }
            printf("\n");
            Imprimir(tabuleiro, n);
            break;
       case 3:
           while (qtdRainhas < n)
           {
                if (testaLinha(tabuleiro, i-1, j-1, n))
                {
                    if (testaColuna(tabuleiro, i-1, j-1, n))
                    {
                        if (!verificaConflitos(i-1, j-1, tabuleiro, n))
                        {
                             tabuleiro[i] [j] = 1;
                             qtdRainhas++;
                             printf("Inseriu rainha ");
                        }
                    }
                    else j++;
                }
                else i++;
            }
            printf("\n");
            Imprimir(tabuleiro, n);
           break;
       default:
            printf("\nOpcao invalida!");
	}

   LiberarMatriz(n, tabuleiro);
}

cabecalho.h

#ifndef CABECALHO_H_INCLUDED
#define CABECALHO_H_INCLUDED
#include "funcoes.c"

/**Imprime todas as posições do tabuleiro*/
void Imprimir(int **tabuleiro, int n);
/**VERIFICA SE É POSSÍVEL POSICIONAR A RAINHA EM matriz(ri, rj).
RETORNA 1 SE NÃO É POSSÍVEL E 0 SE FOR POSSÍVEL*/
int verificaConflitos (int ri, int rj, int **tabuleiro, int n);
/**ALOCA A MATRIZ DINAMICAMENTE DE TAMANHO N*N*/
void construirMatriz(int **tabuleiro, int n);
/*TESTAR SE EXISTE RAINHA NA LINHA
RETORNA 1 SE NÃO EXISTE RAINHA NA LINHA*/
int testaLinha(int **tabuleiro, int ri, int rj, int n);
/*TESTA SE EXISTE RAINHA NA COLUNA
RETORNA 1 SE NÃO EXISTE RAINHA NA LINHA COLUNA*/
int testaColuna(int **tabuleiro, int ri, int rj, int n);
/*LIBERA A MEMÓRIA*/
void LiberarMatriz(int n, int **matriz);

#endif // CABECALHO_H_INCLUDED

funcoes.c

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

void construirMatriz(int **tabuleiro, int n)
{
	int i, j;

	tabuleiro = (int**) malloc (n * sizeof(int*));
    for (i = 0; i < n; i++)
    	tabuleiro[i] = (int *) malloc (n * sizeof(int));
    for (i = 0; i < n; i++)
        for (j = 0; j < n; j++)
            tabuleiro[i] [j] = 0;
}

int testaLinha(int **tabuleiro, int ri, int rj, int n)
{
	int i, teste;
	/**TESTA SE EXISTE ALGUMA RAINHA NA MESMA LINHA*/
    for (i = 0; i < n; i++)
    {
        if (tabuleiro[ri][i] == 1)
            return 0;//EXISTE RAINHA NA LINHA(POSIÇÃO INVÁLIDA)
    }
    return 1;//NÃO EXISTE RAINHA NA LINHA(POSIÇÃO VÁLIDA)
}

int testaColuna(int **tabuleiro, int ri, int rj, int n)
{
	int i, teste;
	/**TESTA SE EXISTE ALGUMA RAINHA NA COLUNA*/
    for (i = 0; i < n; i++)
    {
        if (tabuleiro[i][rj] == 1)
            return 0;//EXISTE RAINHA NA COLUNA(POSIÇÃO INVÁLIDA)
    }
    return 1;//NÃO EXISTE RAINHA NA COLUNA(POSIÇÃO VÁLIDA)
}

int verificaConflitos (int ri, int rj, int **tabuleiro, int n)
{
    int i, i1, i2, j, j1, j2;
    int teste = 0;

    i1 = ri;
    i2 = ri;
    j1 = rj;
    j2 = rj;
    printf("\nentrou verificaConflito");
    /**TESTA SE EXISTE ALGUMA NA MESMA LINHA OU COLUNA*/
    for (i = 0; i < n; i++)
    {
        printf("\nentrou for");
        if (tabuleiro[ri][i] == 1 || tabuleiro[i][rj] == 1)
        {
            teste = 1;
            printf("\nentrou if");
            break;
        }
        printf("\nsaiu for");
    }
    printf("\ntestou linha e coluna");
    if (teste == 0)
    {
        /**ACHA INICIO DA DIAGONAL PRINCIPAL*/
        while (i1 > 0 && j1 > 0)
        {
            i1--;
            j1--;
        }
        /**ACHA INICIO DA DIAGONAL SECUNDÁRIA*/
        while (i2 > 0 && j2 < (n-1))
        {
            i2--;
            j2++;
        }
        /**TESTE DIAGONAL PRINCIPAL*/
        for (i = i1; i < ((n-1) - i1); i++, j1++)/**LINHA E COLUNA*/
        {
            if (i != ri && j1 != rj && tabuleiro[i][j1] == 1)
            {
                    teste = 1;
                    break;
            }
        }
        printf("\ntestou diagonal primaria");
        /**TESTE DIAGONAL SECUNDARIA*/
        for (i = i2; i < ((n-1) - i2); i++, j2--)/**LINHA E COLUNA*/
        {
            if (i != ri && j2 != rj && tabuleiro[i][j2] == 1)
            {
                    teste = 1;
                    break;
            }
        }
        printf("\ntestou diagonal secundaria");
    }

    return teste;
}


void Imprimir(int **tabuleiro, int n)
{
    int i, j;

    printf("\n");
    for (i = 0; i < n; ++i)
    {
        for (j = 0; j < n; ++j)
            printf("%i ", tabuleiro[i][j]);
        printf("\n");
    }
}

void LiberarMatriz(int n, int **matriz)
{
  int  i;

  if (matriz == NULL)
  	return;

  for (i = 0; i < n; i++)
  	free (matriz[i]);/* LIBERA AS LINHAS DA MATRIZ*/

 free (matriz);/* LIBERA A MATRIZ */
}

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

 

9 minutos atrás, felipinho2feh disse:

Não existe isso, internamente, um arranjo bidimensional é um ponteiro de ponteiro.

Me manda como você alocou esse tabuleiro, eu testei sua função aqui e deu certo, eu aloquei o tabuleiro e testei valores aleatorios e rodou normal.

  kk

Compartilhar este post


Link para o post
Compartilhar em outros sites

agora vi jovem, achei o erro. Como disse na alocação da matriz

adicionado 0 minutos depois

Na função construir matriz você precisa retornar o ponteiro, porque a partir do momento que você envia o ponteiro e da malloc, o endereço não é necessariamente o mesmo.

adicionado 1 minuto depois

int** construirMatriz(int **tabuleiro, int n)
{
    int i, j;

    tabuleiro = (int**)malloc(n * sizeof(int*));
    for (i = 0; i < n; i++)
        tabuleiro = (int *)malloc(n * sizeof(int));
    for (i = 0; i < n; i++)
        for (j = 0; j < n; j++)
            tabuleiro [j] = 0;
            
            return tabuleiro;
}

 

tabuleiro = construirMatriz(tabuleiro, n);

 

mude isso e funcionará =D

adicionado 2 minutos depois

@Mauro Britivaldo ? Não entendi.

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

@felipinho2feh errei na solução, obrigado.

adicionado 2 minutos depois

agora só aguardo o feedback...

Compartilhar este post


Link para o post
Compartilhar em outros sites

Só pra saber. Estou compilando com o gcc aqui, estou sem tempo no momento, mas fiz alguns testes e parece ter erro de logica, porque alguns funcionam outros não. De cara já vi você acessando memoria que não te pertence no main. Da uma revisada no código.

 

if (verifica == 0)
                {
                    printf("\nentrou if\n");
                    tabuleiro[ri][rj] = 1;
                    printf("Inseriu rainha %i" , i);
                    qtdRainhas++;

 }

 

Nessa parte mesmo. Seria ri - 1, rj - 1.

Compartilhar este post


Link para o post
Compartilhar em outros sites

A função construirMatriz em sua implementação, cria um vetor de ponteiros. Os resultados de acesso à memória são imprevisíveis, e no caso em questão, acontece um acesso violado a memória.

Troque a implementação de forma a criar um vetor de inteiros; há necessidade de mais uma etapa na função!

Compartilhar este post


Link para o post
Compartilhar em outros sites
14 minutos atrás, Mauro Britivaldo disse:

 

A função construirMatriz em sua implementação, cria um vetor de ponteiros. Os resultados de acesso à memória são imprevisíveis, e no caso em questão, acontece um acesso violado a memória.

Troque a implementação de forma a criar um vetor de inteiros; há necessidade de mais uma etapa na função!

 

Não jovem. 

Você aloca memória para um vetor de ponteiros. Então para cada ponteiro você aloca um vetor de inteiros.

Compartilhar este post


Link para o post
Compartilhar em outros sites
1 minuto atrás, felipinho2feh disse:

Não jovem. 

Você aloca memória para um vetor de ponteiros. Então para cada ponteiro você aloca um vetor de inteiros.

Na função não existe a eta de interios, ela acaba com x = (int *) que é diferente de x = (int). Por isso há mais uma etapa.

Só acho!!!

adicionado 1 minuto depois

Todos os ponteiros apontam para 0 ou 1 na memória

Compartilhar este post


Link para o post
Compartilhar em outros sites
agora, Mauro Britivaldo disse:

Na função não existe a eta de interios, ela acaba com x = (int *) que é diferente de x = (int). Por isso há mais uma etapa.

Só acho!!!

Não. É assim:

você declara um ponteiro de ponteiro para inteiro ->   int **m;

Então o que você faz? Em uma matriz n x n você aloca n ponteiros para int ->   m = (int**)malloc( n*sizeof(int*) );

Depois, para cada ponteiro de inteiro você aloca um arranjo de inteiros de tamanho n ->  for(i = 0; i< n; i++) m = (int*)malloc( n*sizeof(int))

 

Logo você tem uma matriz de inteiros, que nada mais é que um vetor de vetores. O problema é que na maioria das instituições e cursos, ensinam o modo amador de declarar vetores, por isso a confusão.

Espero que tenha entendido.

Compartilhar este post


Link para o post
Compartilhar em outros sites
5 horas atrás, Vitor Avancini disse:

void construirMatriz(int **tabuleiro, int n) { 
	int i, j; tabuleiro = (int**) malloc (n * sizeof(int*)); //>Ponteiros para ponterios enésimo
		for (i = 0; i < n; i++) 
             tabuleiro[i] = (int *) malloc (n * sizeof(int)); //> Ponterios para interios enésimo
         
        for (i = 0; i < n; i++) 
          for (j = 0; j < n; j++)
              tabuleiro[i] [j] = 0; //> Todos aponta para o local 0 na memoria, #Error
 }

 

 

adicionado 7 minutos depois

Basicamente o que acontece é isto:

int main(void) {
  int **Array_ptr, *ptr;
  int value;

    Array_ptr[0] = ptr;
    printf("Vai dar crash? %d\n\n", Array_ptr[0][0] );

  return 0;
}

 

Compartilhar este post


Link para o post
Compartilhar em outros sites
18 minutos atrás, Mauro Britivaldo disse:

 

Não.

tabuleiro[j] = 0 é equivalente a: *( *( tabuleiro + i ) + j ) = 0;

 

Ou seja, não existe apontar pro local zero de memória, e sim definir os inteiros da matriz como 0

Compartilhar este post


Link para o post
Compartilhar em outros sites
#include <stdio.h>
#include <stdlib.h>

int main(void) {

  int **ptr_array;

      ptr_array = (int**) calloc( 1, sizeof (int**) );  //1 step
      ptr_array[0] = (int*) calloc( 1, sizeof (int*) ); //2 step
      ptr_array[0][0] = (int) calloc(1, sizeof (int) ); //3 step


      ptr_array[0][0] = 1;
      printf("Nao da crash %d\n\n", ptr_array[0][0] );
  return 0;
}

 

Compartilhar este post


Link para o post
Compartilhar em outros sites
8 minutos atrás, Vitor Avancini disse:

eu tentei inicializar a matriz colocando 0 em todas as posições, não foi isso que aconteceu?

Sim, você fez certo.

Poderia alocar usando calloc ao invés de malloc, é uma opção. 

Usando calloc você tem todos os inteiros como 0 por default

Compartilhar este post


Link para o post
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisar ser um membro 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 publicações 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

×