Beraldo 864 Denunciar post Postado Agosto 31, 2008 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
gRoOvE 0 Denunciar post Postado Agosto 31, 2008 Beraldo, de uma olhada nesses links, vai te ajudar a resolver :D http://forum.imasters.com.br/index.php...l=free++matriz* http://www.boreki.eng.br/Tutoriais/linuxall/ponteiros.htm Compartilhar este post Link para o post Compartilhar em outros sites
_Isis_ 202 Denunciar post Postado Agosto 31, 2008 Breakpoint 2, main () at vet.c:5353 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
gRoOvE 0 Denunciar post Postado Agosto 31, 2008 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
_Isis_ 202 Denunciar post Postado Agosto 31, 2008 *(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
gRoOvE 0 Denunciar post Postado Setembro 1, 2008 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
_Isis_ 202 Denunciar post Postado Setembro 1, 2008 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
Beraldo 864 Denunciar post Postado Setembro 1, 2008 Beraldo, de uma olhada nesses links, vai te ajudar a resolver :D http://forum.imasters.com.br/index.php...l=free++matriz* http://www.boreki.eng.br/Tutoriais/linuxall/ponteiros.htm 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
Kandrade 7 Denunciar post Postado Setembro 1, 2008 Voce quer copiar todos os endereços dos ponteiros em v6? Pois nesses casos só está copiando o primeiro de cada ponteiro. Compartilhar este post Link para o post Compartilhar em outros sites
_Isis_ 202 Denunciar post Postado Setembro 1, 2008 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
Kandrade 7 Denunciar post Postado Setembro 1, 2008 O código da Isis guarda o primeiro endereço de cada ponteiro e como a alocação é sequencial o i e o j definem qual conteúdo será mostrado. http://forum.imasters.com.br/public/style_emoticons/default/thumbsup.gif Compartilhar este post Link para o post Compartilhar em outros sites
_Isis_ 202 Denunciar post Postado Setembro 1, 2008 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
Kandrade 7 Denunciar post Postado Setembro 1, 2008 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
_Isis_ 202 Denunciar post Postado Setembro 1, 2008 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
gRoOvE 0 Denunciar post Postado Setembro 1, 2008 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
_Isis_ 202 Denunciar post Postado Setembro 1, 2008 Eu colei minha execução. Se aqui dá certo debugue aí o teu. Compartilhar este post Link para o post Compartilhar em outros sites
gRoOvE 0 Denunciar post Postado Setembro 2, 2008 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
_Isis_ 202 Denunciar post Postado Setembro 2, 2008 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
gRoOvE 0 Denunciar post Postado Setembro 4, 2008 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