AJBM Posted September 16, 2013 at 06:46 PM Report #524794 Posted September 16, 2013 at 06:46 PM Boas! Eu tenho este codigo. typedef struct { int bi; } Pessoa; typedef struct { Pessoa pessoas[10]; int nelementos; } Pessoas; int find(Pessoas *pessoas, Pessoa *pessoa) { int i; for (i = 0; i < pessoas->nelementos; i++) { if (pessoas->pessoas[i].bi == pessoa->bi) { return i; } } return (-1); } void removePessoa(Pessoas *pessoas, Pessoa *pessoa) { int pos = find(&pessoas, &pessoa); if (pos != (-1)) { int i; for (i = 0; i < pos; i++) { pessoas->pessoas[i] = pessoas->pessoas[i]; } for (i = pos + 1; i < pessoas->nelementos; i++) { pessoas->pessoas[i - 1] = pessoas->pessoas[i]; } pessoas->nelementos--; } } int main(int argc, char** argv) { Pessoas pessoas; pessoas.nelementos = 0; Pessoa pessoa; pessoa.bi = 10; Pessoa pessoa2; pessoa2.bi = 20; Pessoa pessoa3; pessoa3.bi = 30; Pessoa pessoa4; pessoa4.bi = 40; addPessoa(&pessoas, &pessoa); addPessoa(&pessoas, &pessoa2); addPessoa(&pessoas, &pessoa3); addPessoa(&pessoas, &pessoa4); listar(&pessoas); removePessoa(&pessoas, &pessoa3); printf("\n\n"); listar(&pessoas); return (EXIT_SUCCESS); } A função find por algum motivo não esta a funcionar correctamente e não percebo porque. Não remove a pessoa que eu passo remove sempre a pessoa2. Se eu colocar a posição directamente já remove. Também estou com um problema com o debug eu estou a utilizar o netbeans e quando faço debug aparece um erro GDB has unexpectedly stopped with return -1.073.741.515
HappyHippyHippo Posted September 16, 2013 at 07:34 PM Report #524799 Posted September 16, 2013 at 07:34 PM (edited) vamos lá por pontos : 1 - a tua "interface" das funções não se entram num modelo "interessante". achas que faz sentido estares a instanciar uma estrutura pessoa para a poderes inserir/procurar/remover da lista ? não as tuas funções deveriam ter os seguintes protótipos: #define TAMANHO_NOME 256 typedef struct Pessoa { char nome[TAMANHO_NOME]; int bi; } Pessoa; Pessoa * addPessoa(Pessoas * lista, char * nome, int bi); Pessoa * findPessoa(Pessoas * lista, int bi); void removePessoa(Pessoas * lista, int bi); isto facilita a interações com a lista que estás a tentar criar 2 - tirando o problema anterior o problema não se encontra na função find mas na maneira que a estás a chamar: int find(Pessoas *pessoas, // tipo de dados do argumento : ponteiro para a lista Pessoa *pessoa) { // tipo de dados do argumento : ponteiro para o elemento com os dados a serem inseridos // ... } int removePessoa(Pessoas *pessoas, // tipo de dados do argumento : ponteiro para a lista Pessoa *pessoa) { // tipo de dados do argumento : ponteiro para o elemento com os dados a serem inseridos int pos = find(&pessoas, // que tipo de dados é este ? &pessoa); // que tipo de dados é este ? 3 - o teu código de limpeza da lista não só é desnecessário como tem elementos que não fazem nada: // isto não faz absolutamente nada for (i = 0; i < pos; i++) { pessoas->pessoas[i] = pessoas->pessoas[i]; } // isto pode ser simplificado for (i = pos + 1; i < pessoas->nelementos; i++) { pessoas->pessoas[i - 1] = pessoas->pessoas[i]; } tudo o código apresentado anteriorment pode ser alterado pela linha: memmove(pessoas->pessoas[pos], // destino da cópia pessoas->pessoas[pos + 1], // elementos a serem movidos sizeof(Pessoa) * (pessoas->nelementos - pos - 1)); // quantidade de bytes a serem movidos 4 - nota que nos protótipos que te apresentei não trabalha com o indice, isto porque o ponteiro para o elemento do array já tem em si, a informação necessária sobre o indice do elemento. olha para o seguinte exemplo: Pessoas * pessoas; Pessoa * p = &pessoas->pessoas[0]; // p tem o valor da posição de memória do primeiro elemento do array p = &pessoas->pessoas[1]; // p tem o valor da posição de memória do primeiro elemento do array mais o tamanho desse elemento p = &pessoas->pessoas[2]; // p tem o valor da posição de memória do primeiro elemento do array mais o tamanho dos dois primeiros elementos p = &pessoas->pessoas[0] + sizeof(Pessoa) * 4); // p aponta para o quinto elemento da lista int indice = (p - &pessoas->pessoas[0]) / sizeof(Pessoa); // indice terá o valor de 5; // NOTA : p = (Pessoa *) pessoas; // p tambem aponta para o primeiro elemento da lista, mas isto é por outras razões que tem haver com o "empacotamento" dos dados em meória Edited September 16, 2013 at 07:35 PM by HappyHippyHippo IRC : sim, é algo que ainda existe >> #p@p Portugol Plus
AJBM Posted September 16, 2013 at 09:29 PM Author Report #524816 Posted September 16, 2013 at 09:29 PM
HappyHippyHippo Posted September 16, 2013 at 10:23 PM Report #524820 Posted September 16, 2013 at 10:23 PM &pessoas- é um apontador para Pessoas. &pessoa-é um apontador a Pessoa. errado vê bem o que estás a fazer/escrever e principalmente olha para as mensagens do teu compilador IRC : sim, é algo que ainda existe >> #p@p Portugol Plus
AJBM Posted September 17, 2013 at 09:51 AM Author Report #524852 Posted September 17, 2013 at 09:51 AM O meu compilador não apresenta warmings nem erros. Mas penso que ja descobri, se eu fizer isto find(pessoas,pessoa) ja funciona. Eu na função remover já passo o endereço para pessoa, e no find ao fazer isto &pessoa, estava a passar o endereço do apontador e não o endereço do valor que eu quero. Ou seja isto &pessoa representa o endereço do apontador para pessoa, e não o endereço de pessoa.
pikax Posted September 17, 2013 at 09:55 AM Report #524853 Posted September 17, 2013 at 09:55 AM Utiliza a flag -Wall no compilador para te dar todos os warnings. Por muito mais que que estude só aprendo uma coisa, que ainda tenho muita coisa para aprender. A beleza de um código está em decompor problemas complexos em pequenos blocos simples. "learn how to do it manually first, then use the wizzy tool to save time." "Kill the baby, don't be afraid of starting all over again. Fail soon, learn fast."
AJBM Posted September 17, 2013 at 09:58 AM Author Report #524854 Posted September 17, 2013 at 09:58 AM Eu estou no netbeans, e tenho Warming level More Warmings
pikax Posted September 17, 2013 at 10:03 AM Report #524855 Posted September 17, 2013 at 10:03 AM o compilador nao da' warning nesta linha? int pos = find(&pessoas, &pessoa); Por muito mais que que estude só aprendo uma coisa, que ainda tenho muita coisa para aprender. A beleza de um código está em decompor problemas complexos em pequenos blocos simples. "learn how to do it manually first, then use the wizzy tool to save time." "Kill the baby, don't be afraid of starting all over again. Fail soon, learn fast."
AJBM Posted September 17, 2013 at 10:11 AM Author Report #524857 Posted September 17, 2013 at 10:11 AM o compilador nao da' warning nesta linha? Agora da eu antes tinha some warning e não dava, mudei para more warnings e já da. Como tinha corrigido o find antes de mudar o nível de warnings não mostrava nada.
AJBM Posted September 17, 2013 at 07:04 PM Author Report #524931 Posted September 17, 2013 at 07:04 PM Fiz umas alterações ao código. Aparentemente esta tudo a funcionar. Obrigado pela ajuda! 👍 Pessoa * addPessoa(Pessoas *pessoas, Pessoa *pessoa) { pessoas->pessoas[pessoas->nelementos] = *pessoa; pessoas->nelementos++; return &(pessoas->pessoas[pessoas->nelementos-1]); } Pessoa * find(Pessoas *pessoas, int bi) { int i; for (i = 0; i < pessoas->nelementos; i++) { if (pessoas->pessoas[i].bi == bi) { return &(pessoas->pessoas[i]); } } return NULL; } /** * * * @param pessoas * @param pessoa */ int removePessoa(Pessoas *pessoas, int bi) { Pessoa *pos = find(pessoas, bi); if (pos != NULL) { memmove(pos, pos + 1,sizeof(Pessoa)*(&(pessoas->pessoas[pessoas->nelementos-1])-pos)); pessoas->nelementos--; return 1; } return 0; } void listar(Pessoas *pessoas) { int i; for (i = 0; i < pessoas->nelementos; i++) printf("Bi: %d\n", pessoas->pessoas[i].bi); }
HappyHippyHippo Posted September 17, 2013 at 07:16 PM Report #524932 Posted September 17, 2013 at 07:16 PM já testaste o código ? é que a mim parece que andas ai com acessos inválidos de memória ... além de continuares com código que te obriga a instânciar uma estrutura Pessoa para inserir na lista IRC : sim, é algo que ainda existe >> #p@p Portugol Plus
AJBM Posted September 17, 2013 at 08:36 PM Author Report #524937 Posted September 17, 2013 at 08:36 PM testei e não deu problemas. int main(int argc, char** argv) { Pessoas pessoas; pessoas.nelementos = 0; addPessoa(&pessoas, 10); addPessoa(&pessoas, 20); addPessoa(&pessoas, 30); addPessoa(&pessoas, 40); listar(&pessoas); removePessoa(&pessoas, 20); printf("\n\n"); listar(&pessoas); addPessoa(&pessoas, 50); removePessoa(&pessoas, 40); printf("\n\n"); listar(&pessoas); addPessoa(&pessoas,40); printf("\n\n"); listar(&pessoas); return (EXIT_SUCCESS); } Em relação a instanciar Pessoa, para inserir na lista esta errado? Pessoa * addPessoa(Pessoa *lista,Pessoa *pessoa) Pessoa * addPessoa(Pessoa *lista,int bi)
HappyHippyHippo Posted September 17, 2013 at 09:00 PM Report #524941 Posted September 17, 2013 at 09:00 PM (edited) faz as contas memmove(pos, pos + 1, sizeof(Pessoa) * (&(pessoas->pessoas[pessoas->nelementos-1]) - pos)); //sizeof(Pessoa) = tamanho de cada elemento //&(pessoas->pessoas[pessoas->nelementos-1] = posição de memória do primeiro byte do último elemento //pos = posição de memória do primeiro byte do elemento a ser removido caso exemplo : remover o penúltimo elemento a soma total deverá ser igual ao tamanho de 1 elemento >> sizeof(Address) * 1 (o último elemento) o teu código: sizeof(Pessoa) + <posição último elemento> - <posição elemento removido (penúltimo)> = sizeof(Pessoa) + &(pessoas->pessoas[pessoas->nelementos-1] - &(pessoas->pessoas[pessoas->nelementos-2] = sizeof(Pessoa) + sizeof(Pessoa) = sizeof(Pessoa) * 2 caso exemplo : remover o ante-ante-penúltimo elemento a soma total deverá ser igual ao tamanho de 3 elementos >> sizeof(Address) * 3 (os trés último elementos) o teu código: sizeof(Pessoa) + <posição último elemento> - <posição elemento removido (penúltimo)> = sizeof(Pessoa) + &(pessoas->pessoas[pessoas->nelementos-1] - &(pessoas->pessoas[pessoas->nelementos-4] = sizeof(Pessoa) + sizeof(Pessoa) * 3 = sizeof(Pessoa) * 4 ... como vês ... está errado não está errado, mas não faz muito sentido em termos de lógica criar um elemento para criar um elemento Edited September 17, 2013 at 09:01 PM by HappyHippyHippo IRC : sim, é algo que ainda existe >> #p@p Portugol Plus
AJBM Posted September 18, 2013 at 10:50 AM Author Report #524986 Posted September 18, 2013 at 10:50 AM (edited) int removePessoa(Pessoas *pessoas, int bi) { Pessoa *pos = find(pessoas, bi); if (pos != NULL) { memmove(pos, pos + 1, sizeof (Pessoa)* (&(pessoas->pessoas[pessoas->nelementos - 1]) - pos)); printf("%d %d %d", pos, &(pessoas->pessoas[pessoas->nelementos - 1]), sizeof (Pessoa)* (&(pessoas->pessoas[pessoas->nelementos - 1]) - pos)); pessoas->nelementos--; return 1; } return 0; } int main(int argc, char** argv) { Pessoas pessoas; pessoas.nelementos = 0; addPessoa(&pessoas, 10); addPessoa(&pessoas, 20); addPessoa(&pessoas, 30); addPessoa(&pessoas, 40); listar(&pessoas); // removePessoa(&pessoas, 30); //removePessoa(&pessoas, 20); removePessoa(&pessoas, 10); } Penúltimo caso (30) Output printf: 2272268 2272272 4- corresponde a uma pessoa Antepenúltimo caso(20): Output printf: 2272264 2272272 8-- corresponde a 2 pessoa Primeiro (10) Output printf: 2272260 2272272 12-- corresponde a 3 pessoa Edited September 18, 2013 at 10:51 AM by AJBM
HappyHippyHippo Posted September 18, 2013 at 10:56 AM Report #524987 Posted September 18, 2013 at 10:56 AM (edited) epá .. mas tu leste o meu post ??? não percebeste onde está o erro ? vi agora que o erro estava na minha leitura do teu código. estava a ler um '+' onde tinhas um '*', o que invalida a explicação anterior Edited September 18, 2013 at 10:59 AM by HappyHippyHippo IRC : sim, é algo que ainda existe >> #p@p Portugol Plus
AJBM Posted September 18, 2013 at 11:31 AM Author Report #524993 Posted September 18, 2013 at 11:31 AM ok. não está errado, mas não faz muito sentido em termos de lógicacriar um elemento para criar um elemento Se pessoa tivesse por exemplo 10 atributos. Não fazia sentido muito sentido passar os 10 atributos numa função.
HappyHippyHippo Posted September 18, 2013 at 11:35 AM Report #524995 Posted September 18, 2013 at 11:35 AM ok. Se pessoa tivesse por exemplo 10 atributos. Não fazia sentido muito sentido passar os 10 atributos numa função. nunca viste a CreateWindowEx ... IRC : sim, é algo que ainda existe >> #p@p Portugol Plus
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now