Jump to content
sustohouse

Matriz dinâmica malloc & realloc

Recommended Posts

sustohouse

Ora viva  ;)

Ando aqui com um trabalho da faculdade, e agora estou com uma duvida na alocação da memória dinâmica.

Estou a fazer o seguinte

                int **matriz; 
	//cria matriz dinamico
	matriz=(int **) malloc(linhas*sizeof(int *));

	for (i=0; i<linhas; i++)
		matriz[i]=(int *) malloc(colunas*sizeof(int));

E obtenho o array com o tamanho que pretendo, e passa a ser a ser acessível por matriz[linha][coluna].

A minha duvida aparece a seguir quando tenciono aumentar o array 1 linha e 1 coluna sempre que uma condição se verifique.

             linhas++;
     colunas++;
             
             matriz=(int **) realloc(matriz, linhas*sizeof(int *) );
             matriz[i]=(int *) realloc(matriz[i], colunas*sizeof(int));

O que estou a fazer de errado?

Share this post


Link to post
Share on other sites
Localhost

Boas,

Para fazer isso primeiro tens que perceber bem o que estás a fazer no código que mostraste.

Na primeira linha (depois da declaração da variável matriz) tu estás a alocar dinamicamente um vector de ponteiros, neste caso com sizeof (int) * N (vou chamar N à tua variável linhas para facilitar) bytes, ou seja, estás a alocar N ponteiros do tipo int. Depois disso, para cada um desses ponteiros tu alocas um vector com M elementos (M = colunas). Se tu queres aumentar a tua matriz vais ter que alocar mais um ponteiro (para além daqueles que já tens), ou seja, N + 1 ponteiros e depois, *para cada um dos ponteiros que tens* tens que alocar M + 1 elementos.

*UPDATE*

Estava a escrever o post aos poucos e acabei por não ver o teu edit.

Vou-te deixar aqui um pequeno código que te demonstra onde estás a falhar. Falta-te um ciclo porque tu queres alocar para todos os elementos do vector de ponteiros. Daí teres de perceber bem o que eu estava a dizer atrás.

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

#define N_POINTERS 10
#define M_ELEMENTS 10

int main (void)
{	
int **my_matrix = NULL, i = 0, j = 0;

my_matrix = (int **) malloc (sizeof (int) * N_POINTERS);
for (i = 0; i < N_POINTERS; i++)
{
	my_matrix[i] = (int *) malloc (sizeof (int) * M_ELEMENTS); 
	for (j = 0; j < M_ELEMENTS; j++)
		my_matrix[i][j] = j + 1;
}

my_matrix = (int **) realloc (my_matrix, sizeof (int) * (N_POINTERS + 1));
for (i = 0; i < N_POINTERS + 1; i++)
	my_matrix[i] = (int *) realloc (my_matrix[i], sizeof (int) * (M_ELEMENTS + 1)); 

return 0;
}


here since 2009

Share this post


Link to post
Share on other sites
sustohouse

Obrigado pelo apoio desde já. Sim eu na teórica entendo o que fiz e o que necessito de fazer.

A minha duvida está "na prática" em voltar a alocar memoria.

Se a condição se verificar para o caso do N (linhas), eu incremento a variável e ela ganha o novo valor.

Ao fazer

   matriz=(int **) realloc(matriz, N*sizeof(int *) );

Estou a alocar mas um ponteiro que fará de nova linha?

No caso de M (colunas) tenho duvidas.

Share this post


Link to post
Share on other sites
Localhost

Vê o código que deixei no meu update. Tem as linhas mais importante em highlight.


here since 2009

Share this post


Link to post
Share on other sites
sustohouse

Neste momento tenho assim o código


int **matriz=NULL; 

//cria matriz dinamico
matriz=(int **) malloc (sizeof(int)*linhas);

for (i=0; i<linhas; i++)
     matriz[i]=(int *) malloc(sizeof(int)*colunas);


//AUMENTAR a matriz | Quando jogador perder aumenta 1 linha e 1 coluna
matriz=(int **) realloc(matriz, sizeof(int)*(linhas+1) ); 

for (i=0; i<(linhas+1); i++)
	matriz[i]=(int *) realloc(matriz[i], sizeof(int)*(colunas+1));

Continua a me dar erro quando faço que o programa adicione uma nova linha ou coluna, devolve para uma função interna do Visual Studio :S

Share this post


Link to post
Share on other sites
Localhost

Dá mais informação sobre o erro. Experimenta compilar o código que deixei no outro post e verifica se dá o mesmo erro.


here since 2009

Share this post


Link to post
Share on other sites
sustohouse

Unhandled exception at 0x515c700c (msvcr100d.dll) in Trabalho-Pratico.exe: 0xC0000005: Access violation reading location 0xcdcdcdc8.

Sou devolvido para uma função que se encontra em dbgheap.c numa função que refere ser de Memory management

----

Mesmo com aquele exemplo me devolve o mesmo erro.

Share this post


Link to post
Share on other sites
sustohouse

O exemplo está a dar  o erro no realloc 

for (i = 0; i < N_POINTERS + 1; i++)

se o ciclo só for até N_POINTERS Ok! Ou seja está a alocar mal a linha anterior que supostamente criaria mais um ponteiro para linha.

Share this post


Link to post
Share on other sites
Localhost

Aqui funciona perfeitamente. Já aumentei com vários tamanhos e resulta sempre. Mostra o código todo ou pelo menos a parte em que queres implementar isto.


here since 2009

Share this post


Link to post
Share on other sites
sustohouse

Acredito que assim que o exemplo corra o meu também irá correr.

Que compilador estás a usar? Aqui o exemplo também rebenta.

O código que envolve a matriz na questão de criação e alteração de tamanho é o que postei.

Share this post


Link to post
Share on other sites
Localhost

Estou em Linux a utilizar o GCC.

Para tirar as dúvidas executei o código no Ideone e também deu sem problemas. Como não estou em Windows não te posso ajudar a descobrir o erro mas provavelmente está noutro local que não o código em si. Deixo aqui o link para os resultados de execução no Ideone.

http://ideone.com/3m7lV.


here since 2009

Share this post


Link to post
Share on other sites
sustohouse

Não posso usar o gcc, estou a usar duas funções que lá não correm, usadas para imprimir no ecran consoante coordenadas.

Estou a estar estranho é porque que Visual Studio está a dar erro só no realloc, pois

com o malloc tudo ok!

Mais uma vez obrigado

Share this post


Link to post
Share on other sites
sustohouse

http://ideone.com/dyWE2 corre perfeitamente!

Ando aqui parado desde ontem e afinal o problema é do VS. Eu já tinha implementa o realloc desta forma se não estou em erro.

Ver se encontro alguma forma de resolver o problema.

Share this post


Link to post
Share on other sites
sustohouse

Boas,

Questionei o meu professor e após algum tempo entendemos que quando fazer realloc para a nova linha ele faz mas fica sem nada no apontador, era necessário preencher com elementos para a seguir no realloc dos elementos não dar erro no acesso.

deixo o codigo

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

#define N_LINHAS 10
#define N_ELEMENTOS 10

int main (void)
{       
        int **matriz = NULL, i = 0, j = 0;


	//matriz dinamica inicial
        matriz = (int **) malloc (sizeof (int) * N_LINHAS);  //reserva memoria para as linhas iniciais

        for (i = 0; i < N_LINHAS; i++)
        {
                matriz[i] = (int *) malloc (sizeof (int) * N_ELEMENTOS);  //reserva memoria para as colunas iniciais
                for (j = 0; j < N_ELEMENTOS; j++)                         //preenche com valores as celulas da matriz
                        matriz[i][j] = j + 1;
        }
        


	 //nova linha  
        matriz = (int **) realloc (matriz, sizeof(int)*(N_LINHAS + 1));  //realoca a memoria para mais uma linha

	matriz[N_LINHAS] = (int *) malloc (sizeof (int) * N_ELEMENTOS);  //realoca a memoria para elementos da nova linha
	        for (j = 0; j < N_ELEMENTOS; j++) 
				matriz[N_LINHAS][j]=0; //para ser diferente da outra inicializacao


	//nova coluna 
        for (i= 0; i < (N_LINHAS + 1); i++)
	{
                matriz[i] = (int *) realloc (matriz[i], sizeof (int) * (N_ELEMENTOS + 1)); 
			matriz[i][N_ELEMENTOS]=0; //para ser diferente da outra inicializacao

	}

	//leitura
        for (i = 0; i < (N_LINHAS +1 ); i++)
        {
		for (j = 0; j < (N_ELEMENTOS +1 ); j++)
                printf("%d ", matriz[i][j]);
            printf("\n");
	}
	system("pause");
	return 0;
}

Share this post


Link to post
Share on other sites
cearas

desde já queria agradecer este post, ajudou me muito :)

tb tenho um trabalho deste genero ou scalhar ate é o mesmo ;P

cumprimentos, obrigado portugal a programar por existires!

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.