Ir ao conteúdo
  • Cadastre-se
brenojwc

Ajuda - Erro "segmentation fault"

Recommended Posts

Eu tenho que fazer um trabalho de programação para a faculdade com o enunciado conforme a imagem em anexo. Além disso deve respeitar as instruções abaixo:

1. Criar um tipo abstrato de dados para a rede, contendo uma definição de tipo para nós, e outro para os arcos, contendo os campos indicados acima. Inclua na definição de tipo dos nós dois valores inteiros, que serão utilizados no processamento do algoritmo: um para armazenar o custo acumulado até chegar ao nó, e outro para indicar a partir de que nó se chegou ao nó atual.

2. Organizar os nós lidos do arquivo como uma lista. De cada nó parte uma lista, que conterá todos os arcos que partem daquele nó. Usar sempre alocação dinâmica.

Segue abaixo o que eu já fiz em três arquivos:


//Arquivo TAD.h:

#ifndef TAD_H_INCLUDED
#define TAD_H_INCLUDED

//Declaração dos tipos:
typedef struct Arco_str *ApontadorArco;

typedef struct Arco_str {

int numArco, custo, proxNodo;
ApontadorArco proxArco;

} Arco;

typedef struct Nodo_str *ApontadorNodo;

typedef struct Nodo_str {

int numNodo, custoAcum, nodoAnt;
ApontadorArco primeiroArco, ultimoArco;
ApontadorNodo proxNodo;

} Nodo;

typedef struct {

ApontadorNodo primeiroNodo, ultimoNodo;

} TipoListaNodos;

//Declaração das funções:
void FLVazia (TipoListaNodos *lista);

int Vazia (TipoListaNodos lista);

void InsereNodo (TipoListaNodos *lista, int numNodo);

void InsereArco (TipoListaNodos *lista, int numNodo, int numArco);

#endif // TAD_H_INCLUDED



//Arquivo TAD.c:
#include <stdio.h>
#include <stdlib.h>
#include "TAD.h"

void FLVazia (TipoListaNodos *lista){

lista = (TipoListaNodos *) malloc (sizeof (TipoListaNodos));
lista->primeiroNodo = NULL;
lista->ultimoNodo = lista->primeiroNodo;

}

int Vazia (TipoListaNodos lista){

return (lista.primeiroNodo == NULL);

}

void InsereNodo (TipoListaNodos *lista, int numNodo){

if (!Vazia (*lista)){
lista->primeiroNodo = (ApontadorNodo) malloc (sizeof (Nodo));
lista->ultimoNodo = lista->primeiroNodo;
lista->ultimoNodo->numNodo = numNodo;}
else{
lista->ultimoNodo->proxNodo = (ApontadorNodo) malloc (sizeof (Nodo));
lista->ultimoNodo = lista->ultimoNodo->proxNodo;
lista->ultimoNodo->numNodo = numNodo;}

}

void InsereArco (TipoListaNodos *lista, int numNodo, int numArco){

ApontadorNodo aux = lista->primeiroNodo;

while (aux->numNodo != numNodo)
aux = aux->proxNodo;

if (aux->primeiroArco == NULL){
aux->primeiroArco = (ApontadorArco) malloc (sizeof (Arco));
aux->ultimoArco = aux->primeiroArco;
aux->ultimoArco->numArco = numArco;}
else{
aux->ultimoArco->proxArco = (ApontadorArco) malloc (sizeof (Arco));
aux->ultimoArco = aux->ultimoArco->proxArco;
aux->ultimoArco->numArco = numArco;}

}



//Arquivo main:
#include <stdio.h>
#include <stdlib.h>
#include "TAD.h"

int main (){

int i, numNodos, numNodo;
char c;

TipoListaNodos *lista;
FLVazia (lista);//Cria a lista de nodos.

FILE *arquivo = fopen ("entrada.txt", "r");//Lê o arquivo de entrada.
if (!arquivo){
printf ("Erro! Fim do programa.");
exit (1);}

fscanf (arquivo, "%d%c", &numNodos, &c);//Lê o número de nodos.

for (i = 0; i < numNodos && !feof (arquivo); i++){

fscanf (arquivo, "%d%c", &numNodo, &c);
InsereNodo (lista, numNodo);


}

return (0);

}

Quando tento rodar o programa, ele trava na execução da função "InsereNodo" e o debuger acusa o erro "segmentation fault" nas linhas onde a função "malloc" é utilizada.

Alguém sabe como resolver isso?

post-601568-13884953546634_thumb.jpg

Compartilhar este post


Link para o post
Compartilhar em outros sites

De cara não vejo erro no seu código. Vamos fazer um debug básico, dando um printf antes de cada inserção na lista?


fscanf (arquivo, "%d%c", &numNodo, &c);
printf("Nos inseridos: %i. Novo no na lista: %i\n", i, numNodo);
InsereNodo (lista, numNodo);

Compartilhar este post


Link para o post
Compartilhar em outros sites
De cara não vejo erro no seu código. Vamos fazer um debug básico, dando um printf antes de cada inserção na lista?

AlexandreHDK, dei o printf que você sugeriu e ele acusou que nenhum nodo foi inserido. O laço não passou da primeira iteração.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Opa, acho que encontrei o problema

Ao fazer:


void FLVazia (TipoListaNodos *lista){

lista = (TipoListaNodos *) malloc (sizeof (TipoListaNodos));
lista->primeiroNodo = NULL;
lista->ultimoNodo = lista->primeiroNodo;

}

Você está passando como argumento o endereço da lista que foi declarada em main(), só que a alocação e atribuição não surtirão efeito na variável lista dentro de main(), somente dentro de FLVazia(), entende?

Exemplo: imagine que dentro de main, ao declarar a existência da variável lista, o compilador atribuiu o endereço 1234. Quando você chama a função FLVazia, você está passando como argumento este valor 1234, que dentro da função ele entende que é um ponteiro para um TipoListaNodos, e é uma variável local para a função, que ela sobrescreveu com o endereço retornado pela função malloc, por exemplo, 50000. Mas ao sair da função FLVazia, a variável lista dentro de main() continua com o valor 1234.

Então, para resolver, basta modificar um pouco:

TipoListaNodos *lista FLVazia (){
TipoListaNodos *lista;
lista = (TipoListaNodos *) malloc (sizeof (TipoListaNodos));
lista->primeiroNodo = NULL;
lista->ultimoNodo = lista->primeiroNodo;
return lista;
}


//Arquivo main:
#include <stdio.h>
#include <stdlib.h>
#include "TAD.h"

int main (){

int i, numNodos, numNodo;
char c;

TipoListaNodos *lista;
lista = FLVazia ();//Cria a lista de nodos.

...

Compartilhar este post


Link para o post
Compartilhar em outros sites

AlexandreHDK, tentei exatamente o que você sugeriu mas acho que o erro não era aquilo que você apontou.

Quando eu faço uma função que tem como parâmetro um apontador, ela modifica o conteúdo do espaço de memória apontado por ele, mas não muda o conteúdo do apontador, ou seja, não muda o local para onde ele aponta (e é aí que você me deu uma luz). O que estava me causando problemas era que o apontador, na verdade, não estava sendo apontado para nada e, quando eu tentava acessar o conteúdo do local para onde ele apontava (o "nada") o programa dava erro. Então eu fiz as seguintes modificações:


TipoListaNodos *lista;
lista = (TipoListaNodos *) malloc (sizeof (TipoListaNodos));
FLVazia (lista);//Cria a lista de nodos.

ao invés de

TipoListaNodos *lista;
FLVazia (lista);//Cria a lista de nodos.


void FLVazia (TipoListaNodos *lista){

lista->primeiroNodo = NULL;
lista->ultimoNodo = lista->primeiroNodo;

}

ao invés de

void FLVazia (TipoListaNodos *lista){

lista = (TipoListaNodos *) malloc (sizeof (TipoListaNodos));
lista->primeiroNodo = NULL;
lista->ultimoNodo = lista->primeiroNodo;

}

e o programa, por enquanto, está rodando.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisar ser um membro para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora





Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas publicações sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×