Jump to content

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


labtech
 Share

Recommended Posts

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
Link to comment
Share on other sites

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
Link to comment
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

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