Ir para o conteúdo
labtech

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

Mensagens Recomendadas

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;
}

Editado por labtech

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros 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.

Editado por pwseo

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros 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.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!

Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.

Entrar Agora

×

Aviso Sobre Cookies

Ao usar este site você aceita os nossos Termos de Uso e Política de Privacidade. Este site usa cookies para disponibilizar funcionalidades personalizadas. Para mais informações visite esta página.