Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Beraldo

Vetor de ponteiros

Recommended Posts

Estou tentando fazer o seguinte exercício:

Faça um programa que receba interativamente do usuário 5 conjuntos de 5 inteiros cada e armazene cada conjunto em um vetor diferente. Em seguida, para cada elemento de um sexto vetor adicional defina uma referência a cada um dos 5 vetores com inteiros. Ao final, seu programa deve imprimir na tela o conteúdo completo de seu "vetor de vetores'' (i.e., o sexto vetor).

É um programa simples. Mas não quero usar sintaxe de vetor, senão fica fácil, mesmo. Quero fazer somente com ponteiros e alocação dinâmica.

 

Fiz assim:

#include <stdio.h>
#include <malloc.h>

#define NUM_KEYS 5

int main()
{
	int i, j, *v1, *v2, *v3, *v4, *v5, **v6;
	
	v1 = (int *) malloc(NUM_KEYS * sizeof(int));
	v2 = (int *) malloc(NUM_KEYS * sizeof(int));
	v3 = (int *) malloc(NUM_KEYS * sizeof(int));
	v4 = (int *) malloc(NUM_KEYS * sizeof(int));
	v5 = (int *) malloc(NUM_KEYS * sizeof(int));
	
	for (i = 0, j = 1; i < 5; i++, j++)
	{
		*(v1 + i * sizeof(int)) = j;
		printf("v1[%d]=%d\n", i+1, j);
	}
	for (i = 0, j = 6; i < 5; i++, j++)
	{
		*(v2 + i * sizeof(int)) = j;
		printf("v2[%d]=%d\n", i+1, j);
	}
	for (i = 0, j = 11; i < 5; i++, j++)
	{
		*(v3 + i * sizeof(int)) = j;
		printf("v3[%d]=%d\n", i+1, j);
	}
	for (i = 0, j = 16; i < 5; i++, j++)
	{
		*(v4 + i * sizeof(int)) = j;
		printf("v4[%d]=%d\n", i+1, j);
	}
	for (i = 0, j = 21; i < 5; i++, j++)
	{
		*(v5 + i * sizeof(int)) = j;
		printf("v5[%d]=%d\n", i+1, j);
	}
	
		
	v6 = (int **) malloc(5*5*sizeof(int));
	
	*(v6) = v1;
	*(v6 + 5 * sizeof(int)) = v2;
	*(v6 + 5 * 2 * sizeof(int)) = v3;
	*(v6 + 5 * 3 * sizeof(int)) = v4;
	*(v6 + 5 * 4 * sizeof(int)) = v5;
	
	puts("\n\n\n\n");
	
	for (i = 0; i < 5; i++)
	{
		printf("%d => %d\n", i, **(v6++));
	}
	
		
	free(v1);
	free(v2);
	free(v3);
	free(v4);
	free(v5);
	free(*v6);
	
	
	puts("\n");
	
	return 0;
}
É mostrado o primeiro valor: 1. Depois dá falha de segmentação. Acho que o problema está no incremento do vetor v6.

Estou quebrando a cabeça há horas, mas não sei o que há de errado. Alguém sabe me dizer o que fiz de errado?

 

[]s

Beraldo

Compartilhar este post


Link para o post
Compartilhar em outros sites
Breakpoint 2, main () at vet.c:53

53 for (i = 0; i < 5; i++)

3: *v6 = (int *) 0x804b008

2: v6 = (int **) 0x804b080

1: i = 5

(gdb) s

 

Breakpoint 3, main () at vet.c:55

55 printf("%d => %d\n", i, **(v6++));

3: *v6 = (int *) 0x804b008

2: v6 = (int **) 0x804b080

1: i = 0

(gdb) s

0 => 1

53 for (i = 0; i < 5; i++)

3: *v6 = (int *) 0x0

2: v6 = (int **) 0x804b084

1: i = 0

(gdb) s

 

Breakpoint 3, main () at vet.c:55

55 printf("%d => %d\n", i, **(v6++));

3: *v6 = (int *) 0x0

2: v6 = (int **) 0x804b084

1: i = 1

(gdb) s

 

Program received signal SIGSEGV, Segmentation fault.

0x080486ad in main () at vet.c:55

 

 

v6 = (int **) malloc(5*5*sizeof(int));

 

Se você quer 5 posicoes em v6 que apontem para os 5 vetores,porque esta alocando 25 posicoes?

 

 

 
 v6 = (int **) malloc(5*sizeof(int*));
 *(v6) = v1;
 *(v6 + sizeof(int)) = v2;
 *(v6 + 2 * sizeof(int)) = v3;
 *(v6 + 3 * sizeof(int)) = v4;
 *(v6 + 4 * sizeof(int)) = v5;

  puts("\n\n\n\n");

  for (i = 0; i < 5; i++) {
	 for(j=0;j<5;j++)
		 printf("%d,%d => %d\n", i,j, **(v6+i*sizeof(int*))+j);
  }

Compartilhar este post


Link para o post
Compartilhar em outros sites

Mas para alocar uma matriz[N][N], não tem que fazer isso linha a linha?

 

v6 = (int **)malloc(5 * sizeof(int*));
	for(i=0;i<5;i++)
	{
		v6[i] = (int*)malloc(5 * sizeof(int));
	}

Compartilhar este post


Link para o post
Compartilhar em outros sites

*(v6) = v1;

*(v6 + sizeof(int)) = v2;

*(v6 + 2 * sizeof(int)) = v3;

*(v6 + 3 * sizeof(int)) = v4;

*(v6 + 4 * sizeof(int)) = v5;

Compartilhar este post


Link para o post
Compartilhar em outros sites

Não entendi o pq de multiplicar por sizeof(int). Testei do jeito que você colocou mas não deu certo. Olha como fiz:

 

v6 = (int **)malloc(5*sizeof(int*));
	*(v6) = v1;
	*(v6 + 1) = v2;
	*(v6 + 2) = v3;
	*(v6 + 3) = v4;
	*(v6 + 4) = v5;

	puts("\n\n\n\n");

	for(i=0;i<5;i++)
	{
		for(j=0;j<5;j++)
		{
		printf("%d,%d => %d\n", i,j,**(v6+i)+j);
		}
	}

E agora para liberar, segui o exemplo do site do link que eu postei logo acima, mas da erro.

Tem como verificar se a memória foi realmente liberada depois de um free?

for(i=0;i<5;i++)
	{
		free(v6[i]);
	}
	free(v6);

Compartilhar este post


Link para o post
Compartilhar em outros sites

você está mexendo com memória crua. Se não quer usar notação de vetor é só assim p/ determinar o lugar onde salvar o endereços dos outros arrays.

Compartilhar este post


Link para o post
Compartilhar em outros sites
Obrigado pelos links.

Ajudou um pouco, mas ainda não resolvi o problema. :(

 

 

v6 = (int **) malloc(5*5*sizeof(int));

 

Se você quer 5 posicoes em v6 que apontem para os 5 vetores,porque esta alocando 25 posicoes?

Pensei que deveria alocar 25, pois quero um vetor de cinco posições, cada uma apontando para outro vetor de cinco posições.

 

 

	 v6 = (int **) malloc(5*sizeof(int*));
	 *(v6) = v1;
	 *(v6 + sizeof(int)) = v2;
	 *(v6 + 2 * sizeof(int)) = v3;
	 *(v6 + 3 * sizeof(int)) = v4;
	 *(v6 + 4 * sizeof(int)) = v5;
  
	  puts("\n\n\n\n");
  
	  for (i = 0; i < 5; i++) {
		 for(j=0;j<5;j++)
			 printf("%d,%d => %d\n", i,j, **(v6+i*sizeof(int*))+j);
	  }
Dessa forma foram mostradas as cinco primeiras posições, em seguida, erro de segmentação.

Esse "j" fora do ponteiro me pareceu estranho. Tentei colocá-lo dentro do ponteiro de várias formas, mas todas também geraram erro.

Compartilhar este post


Link para o post
Compartilhar em outros sites

isis@linux-0khy:~/src> gcc vet.c -Wall && ./a.out

v1[1]=1

v1[2]=2

v1[3]=3

v1[4]=4

v1[5]=5

v2[1]=6

v2[2]=7

v2[3]=8

v2[4]=9

v2[5]=10

v3[1]=11

v3[2]=12

v3[3]=13

v3[4]=14

v3[5]=15

v4[1]=16

v4[2]=17

v4[3]=18

v4[4]=19

v4[5]=20

v5[1]=21

v5[2]=22

v5[3]=23

v5[4]=24

v5[5]=25

 

 

0,0 => 1

0,1 => 2

0,2 => 3

0,3 => 4

0,4 => 5

1,0 => 6

1,1 => 7

1,2 => 8

1,3 => 9

1,4 => 10

2,0 => 11

2,1 => 12

2,2 => 13

2,3 => 14

2,4 => 15

3,0 => 16

3,1 => 17

3,2 => 18

3,3 => 19

3,4 => 20

4,0 => 21

4,1 => 22

4,2 => 23

4,3 => 24

4,4 => 25

Compartilhar este post


Link para o post
Compartilhar em outros sites

Copiar o endereco de cada elemento no v6 é um tanto sem propósito,já que sabendo o endereco inicial em v6 dá p/ percorrer a memória normalmente (v6 seria uma tabela de segmentos de memória e cada posição p/ acessar um desses 5 segmentos é o offset dentro do segmento)

Compartilhar este post


Link para o post
Compartilhar em outros sites

Não questionei isso não.

Eu concordo com a solução.

 

Copiar o endereco de cada elemento no v6 é um tanto sem propósito,já que sabendo o endereco inicial em v6 dá p/ percorrer a memória normalmente (v6 seria uma tabela de segmentos de memória e cada posição p/ acessar um desses 5 segmentos é o offset dentro do segmento)

Compartilhar este post


Link para o post
Compartilhar em outros sites

eu sei. tô falando que se através de um ponteiro dá p/ acessar as outras posições de memória,nao tem porque ficar copiando tudo.

Compartilhar este post


Link para o post
Compartilhar em outros sites

	 v6 = (int **) malloc(5*sizeof(int*));
	 *(v6) = v1;
	 *(v6 + sizeof(int)) = v2;
	 *(v6 + 2 * sizeof(int)) = v3;
	 *(v6 + 3 * sizeof(int)) = v4;
	 *(v6 + 4 * sizeof(int)) = v5;
  
	  puts("\n\n\n\n");
  
	  for (i = 0; i < 5; i++) {
		 for(j=0;j<5;j++)
			 printf("%d,%d => %d\n", i,j, **(v6+i*sizeof(int*))+j);
	  }
Dessa forma foram mostradas as cinco primeiras posições, em seguida, erro de segmentação.

Esse "j" fora do ponteiro me pareceu estranho. Tentei colocá-lo dentro do ponteiro de várias formas, mas todas também geraram erro.

 

Aqui da erro essa parte *(v6 + 4 * sizeof(int)) = v5, armazena lixo da memória e da erro tb, preciso colocar v6 = (int **) malloc(10*sizeof(int*)) pra dar certo. Na hora de mandar o valor de v5, ele mostra antes o valor certo(21), depois na hora de mandar converte em lixo e se aumentar o tamanho do malloc vai certo "/

Compartilhar este post


Link para o post
Compartilhar em outros sites

Pois eu debuguei e acontece o que eu falei, troca o valor do v5(21) por lixo quando vai atribuir, não sei como...esse debuguer do Visual C++ é um lixo também, não tem informação nenhuma.

O problema está no SO ou no compilador, pois rodei o mesmo código no DEV-C++ que usa debugger GDB, rodou certinho "/

Compartilhar este post


Link para o post
Compartilhar em outros sites

Se alguém mais testar em ports do GCC e der certo contra testes em outro compilador no mesmo ambiente...

Compartilhar este post


Link para o post
Compartilhar em outros sites

v6 = (int **) malloc(5*sizeof(int*));
	 *(v6) = v1;
	 *(v6 + sizeof(int)) = v2;
	 *(v6 + 2 * sizeof(int)) = v3;
	 *(v6 + 3 * sizeof(int)) = v4;
	 *(v6 + 4 * sizeof(int)) = v5;

Mas nesse exemplo que você postou Isis, não vai atribuir todos os valores em uma só linha? Ou os '+' ali somam os índices?

 

v6(0bytes) = v1;
v6(4bytes) = v2;
v6(8bytes) = v3;
Como a memória é contígua, entendo que seria todos da mesma linha "/

 

E quanto ao verificar se um free realmente liberou aquela alocação de memória?

 

Por favor, alguém que usa Windows, testa ai pra ver se retorna o mesmo erro que deu aqui

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.