Jump to content
labtech

[Resolvido]Falha de Segmentação (Pointers)

Recommended Posts

labtech

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 by labtech

Share this post


Link to post
Share on other sites
pwseo

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 by pwseo

Share this post


Link to post
Share on other sites
labtech

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.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • 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.