labtech Posted December 24, 2012 at 04:53 PM Report #488290 Posted December 24, 2012 at 04:53 PM (edited) Ola, eu estou a ter um problema de "Falha de Segmentação" ao executar este codigo no Ubuntu. gcc 4.6.3 #include <stdio.h> #include <stdlib.h> struct aluno_str{ int num; struct aluno *proximo; }; typedef struct aluno_str aluno; void insereAluno(aluno *raiz, int numero){ if(raiz==NULL){ raiz = (aluno *)malloc(sizeof(aluno)); raiz->num=numero; } //printf("%d", raiz->num); } int main(){ aluno *raiz; raiz=NULL; insereAluno(raiz,10); printf("%d\n", raiz->num); getchar(); return 0; } Edited December 24, 2012 at 11:55 PM by labtech
pwseo Posted December 24, 2012 at 07:02 PM Report #488313 Posted December 24, 2012 at 07:02 PM (edited) labtech, O teu código não aloca correctamente a memória para a struct. Se colocares um printf logo após chamares a função insereAluno, repararás que o valor de raiz é '(nil)' (ou seja, um endereço inválido): /* ... */ insereAluno(raiz,10); printf("raiz: %p\n", raiz); /* insere esta linha para veres que raiz é '(nil)' */ printf("%d\n", raiz->num); /* a segfault ocorre aqui */ /* ... */ Uma vez que raiz aponta para o endereço NULL, quando tentas aceder via raiz->num, tens uma segfault. Repara que se removeres esse acesso, o programa funciona normalmente. O importante é perceberes que quando passas o endereço de uma variável para uma função, esse endereço é passado by-value. O que isto significa é que dentro da função insereAluno, a variável raiz é local, e as alterações que lhe fazes não se reflectem na raiz original. Isto significa que dentro da função, a variável raiz assume o endereço da memória recém-alocada, mas a variável raiz da main() é outra completamente diferente, que nunca é tocada. Se não quiseres fazer a alocação de memória directamente na main(), podes sempre abstrair isso para uma função, desta forma: struct foo { /* ... */ }; struct foo* new_foo (void) { struct foo *s = NULL; s = malloc(sizeof(struct foo)); /* não esquecer de fazer error-checks */ return s; /* esta linha é muito importante */ } int main (void) { struct foo *a = NULL; a = new_foo(); /* a função new_foo() devolve o endereço da memória alocada */ /* ... */ return 0; } Neste meu exemplo, a função new_foo aloca memória para uma struct foo e devolve o endereço dessa memória, que por sua vez é atribuído à variável a na função main(). Já que estás com a mão na massa, podes também abstrair a libertação de memória para uma função auxiliar, por uma questão de consistência de API. Outra solução para o teu problema passa pela utilização de apontadores para apontadores. Edited December 24, 2012 at 07:03 PM by pwseo
labtech Posted December 24, 2012 at 11:58 PM Author Report #488333 Posted December 24, 2012 at 11:58 PM Obrigado pela explicação. Isto foi um codigo que demos nas aulas, mas depois deixamos de lado porque não conseguiamos por a dar. É que esta matéria é um pouco complicada de perceber.
falco Posted December 25, 2012 at 12:13 PM Report #488348 Posted December 25, 2012 at 12:13 PM Já agora, muda lá o tópico, a falha de segmentação não é no Linux, é no teu código...
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