Author Topic: Segmentation fault, en lista simplemente ligada en lenguaje C.  (Read 2426 times)

DanielC

  • Newbie
  • *
  • Posts: 8
  • Karma: 0
    • View Profile
Hola, gente. -
Con el tiempo seguramente me irán conociendo porque tengo 64 años y como supondrán ya no tengo posibilidad de concurrir a la universidad para estudiar programación y deducirán también que la gente que conozco (contemporáneos) no tiene ni idea de computadoras, por lo tanto, soy adicto a los foros. -
Les dejo mi programa para ver si pueden ayudarme a solucionar el error de  segmentation fault que me da en la línea 96, les aclaro que estoy estudiando listas simplemente ligadas hace tan solo una semana. -     

Sistema operativo:Linux Mint
Compilo con el IDE:Geany

Code: [Select]
#include <stdio.h>
#include <stdlib.h>

struct nodo{
int dato;
struct nodo *siguiente;
};

struct lista{
struct nodo *primero;
struct nodo *ultimo;
};

struct lista *ingresos( struct lista *L );
struct lista *agregar( struct lista *L, int dato );
struct nodo *crear( int dato );
void ordenar(struct lista *L);
void mostrar(struct lista *L);


int main( void ){
struct lista *Lista = NULL;

ingresos( Lista );
ordenar( Lista );
mostrar( Lista );

free(Lista);
return 0;
}

struct lista *ingresos( struct lista *L ){
int i;

for( i=0; i<7; i++ ){
printf( "\n %d", i );
L = agregar( L, i );
}

return L;
}


struct lista *agregar( struct lista *L, int dato ){
if( L != NULL ){
struct nodo *e = crear( dato );
L->ultimo->siguiente = e;
L->ultimo = e;

return L;
}else{
struct nodo *e = crear( dato );
struct lista *l = calloc( sizeof( struct lista ), 1 );
l->primero = e;
l->ultimo = e;

return l;
}
}

struct nodo *crear( int dato ){
struct nodo *e = calloc( sizeof( struct nodo), 1 );
e->dato = dato;
e->siguiente = NULL;

return e;
}

void ordenar(struct lista *L){
struct nodo *pivote = NULL,*actual = NULL;
int tmp;
if(L != NULL){
pivote = L->primero;
while(pivote != L->ultimo){
actual = pivote->siguiente;
while(actual != NULL){
if(pivote->dato > actual->dato){
tmp = pivote->dato;
pivote->dato = actual->dato;
actual->dato = tmp;
}
actual = actual->siguiente;
    }
pivote = pivote->siguiente;
    }

}
    else{
    printf("Error lista no inicializada");
    }
}

void mostrar(struct lista *L){
struct nodo *auxiliar;
int i=0;
auxiliar = L->primero; //Error

    printf("\n\n Mostrando lista ordenada:\n");

while (auxiliar!=NULL) {
printf( "\n %d", auxiliar->dato);
auxiliar = auxiliar->siguiente;
i++;
}
if (i==0) printf( "\nLa lista está vacía!!\n" );
}

Lo que me llama la atención es que si el ingreso lo efectuó desde la función principal, todo bien. -

Code: [Select]
int main( void ){
struct lista *Lista = NULL;
int i;

for( i=7; i>0; i--){
Lista = agregar( Lista, i );
printf( "\n %d ", i );
}

ordenar( Lista );
mostrar( Lista );

free(Lista);
return 0;
}

Espero que puedan ayudarme.-
Saludos.

chuidiang

  • Administrator
  • Hero Member
  • *****
  • Posts: 5472
  • Karma: 12
    • View Profile
    • Apuntes de programación
Re: Segmentation fault, en lista simplemente ligada en lenguaje C.
« Reply #1 on: Julio 11, 2016, 04:43:20 pm »
Hola:

¿Cual es la línea 96?

Saludos.

DanielC

  • Newbie
  • *
  • Posts: 8
  • Karma: 0
    • View Profile
Re: Segmentation fault, en lista simplemente ligada en lenguaje C.
« Reply #2 on: Julio 11, 2016, 07:02:21 pm »
Hola, muchas gracias por la pronta respuesta, en el código esta comentada la linea del error,
lo obtengo con debuggear porque la compilación finaliza correctamente. -

Saludos.

chuidiang

  • Administrator
  • Hero Member
  • *****
  • Posts: 5472
  • Karma: 12
    • View Profile
    • Apuntes de programación
Re: Segmentation fault, en lista simplemente ligada en lenguaje C.
« Reply #3 on: Julio 11, 2016, 09:29:30 pm »
Hola:

El problema está aquí

Code: [Select]
struct lista *Lista = NULL;

ingresos( Lista );
ordenar( Lista );
mostrar( Lista );

Lista es null. Cuando llamas ingresos(Lista), dentro del método, la rellenas, pero .......... el puntero Lista sigue siendo null. Cuadno pasas un puntero a una función/método, son dos variables distintas

Code: [Select]
struct lista *ListaFuera = NULL;
ingresos( ListaFuera );
...
struct lista *ingresos( struct Lista *L ){
int i;

for( i=0; i<7; i++ ){
printf( "\n %d", i );
L = agregar( L, i );
}

return L;
}

Las variables Lista (fuera) y L (dentro) son variables distintas. Si haces que L tenga un valor (L=agregar...) NO estás cambiando la variable de fuera, que sigue valiendo NULL. Pasar un puntero a un método sirve para compartir con el método la zona de memoria a la que apunta el puntero, pero NO sirve para hacer que el puntero apunte a otro sitio.

Cuando llamas más tarde a  mostrar( Lista );, Lista vale NULL y cuando dentro de ese método haces auxiliar = L->primero; , te da el segmentation fault, ya que NULL->primero da ese error.

Por eso, de la segunda forma si te funciona, ya que haces en el main, dentro del bucle

Lista = agregar( Lista, i );

y así Lista coge un valor (el que devuelve agregar()).

Se bueno.

DanielC

  • Newbie
  • *
  • Posts: 8
  • Karma: 0
    • View Profile
Re: Segmentation fault, en lista simplemente ligada en lenguaje C.
« Reply #4 on: Julio 12, 2016, 03:03:23 am »
Hola. -
Muchas gracias por ocuparte, eso ya lo tengo solucionado ahora me da los errores que dejo a continuación, me parece que estoy equivocado con lo que debe devolver la función, o sea, con devolver struct nodo o struct lista pero como es un tema nuevo no logro encontrar la sintaxis correcta, si en algún momento tienes tiempo y lo revisas te agradecería. -       







Code: [Select]
#include <stdio.h>
#include <stdlib.h>

struct nodo{
int dato;
struct nodo *siguiente;
};

struct lista{
struct nodo *primero;
struct nodo *ultimo;
};

struct lista *ingresos( struct lista *L );
struct lista *agregar( struct lista *L, int dato );
struct nodo *crear( int dato );
struct nodo *ordenar(struct lista *L);
void mostrar(struct lista *L);


int main( void ){
struct lista *Lista = NULL;

Lista = ingresos( Lista );
Lista = ordenar( Lista );
mostrar( Lista );

free(Lista);
return 0;
}

struct lista *ingresos( struct lista *L ){
int i;

for( i=0; i<8; i++ ){
printf( "\n %d", i );
L = agregar( L, i );
}

return L;
}


struct lista *agregar( struct lista *L, int dato ){
if( L != NULL ){
struct nodo *e = crear( dato );
L->ultimo->siguiente = e;
L->ultimo = e;

return L;
}else{
struct nodo *e = crear( dato );
struct lista *l = calloc( sizeof( struct lista ), 1 );
l->primero = e;
l->ultimo = e;

return l;
}
}

struct nodo *crear( int dato ){
struct nodo *e = calloc( sizeof( struct nodo), 1 );
e->dato = dato;
e->siguiente = NULL;

return e;
}

struct nodo *ordenar(struct lista *L){
struct nodo *pivote = NULL,*actual = NULL;
int tmp;
if(L != NULL){
pivote = L->primero;
while(pivote != L->ultimo){
actual = pivote->siguiente;
while(actual != NULL){
if(pivote->dato > actual->dato){
tmp = pivote->dato;
pivote->dato = actual->dato;
actual->dato = tmp;
}
actual = actual->siguiente;
    }
pivote = pivote->siguiente;
    }
}
    else{
    printf("Error lista no inicializada");
    }
return pivote;
}

void mostrar(struct lista *L){
struct nodo *auxiliar;
int i=0;
auxiliar = L->primero;

    printf("\n\n Mostrando lista ordenada:\n");

while (auxiliar!=NULL) {
printf( "\n %d", auxiliar->dato);
auxiliar = auxiliar->siguiente;
i++;
}
if (i==0) printf( "\nLa lista está vacía!!\n" );
}


Saludos.

DanielC

  • Newbie
  • *
  • Posts: 8
  • Karma: 0
    • View Profile
Re: Segmentation fault, en lista simplemente ligada en lenguaje C.
« Reply #5 on: Julio 12, 2016, 06:43:02 am »
Hola. -
Bueno ya lo solucione, pero me queda una duda que luego te voy a consultar en este mismo hilo.

Saludos.

 

ey