Ir ao conteúdo
  • Cadastre-se

Acessar matriz dentro de uma função


Posts recomendados

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

 

Link para o comentário
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:

Link para o comentário
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 */
}

 

Link para o comentário
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
Link para o comentário
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.

Link para o comentário
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!

Link para o comentário
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.

Link para o comentário
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

Link para o comentário
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.

Link para o comentário
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;
}

 

Link para o comentário
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;
}

 

Link para o comentário
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

Link para o comentário
Compartilhar em outros sites

Visitante
Este tópico está impedido de receber novas respostas.

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