Foros del Web » Programación para mayores de 30 ;) » C/C++ »

Problema con lista enlazada en c

Estas en el tema de Problema con lista enlazada en c en el foro de C/C++ en Foros del Web. El problema que tengo es que no me inserta en la lista me los pone todos en vacio en NULL aunque por lo que veo ...
  #1 (permalink)  
Antiguo 17/10/2015, 13:56
 
Fecha de Ingreso: septiembre-2013
Ubicación: Comunidad Valenciana
Mensajes: 4
Antigüedad: 11 años, 3 meses
Puntos: 0
Pregunta Problema con lista enlazada en c

El problema que tengo es que no me inserta en la lista me los pone todos en vacio en NULL aunque por lo que veo la lista me la crea y me enseña todo los valores. Si alquien me puede guiar sobre donde esta el problema o que me falta se lo agradeceria. Aqui os pongo todo

Aqui pongo el resultado que me sale al ejecutarlo.

Resultado al ejecutarlo
Código PHP:
item 0: (null)
item 1: (null)
item 2: (null)
item 3: (null)
item 4: (null)
item 5: (null)
item 6: (null)
item 7: (null)
item 8: (null)
item 9: (null)
list 
length0

--------------------------------
Process exited after 0.0115 seconds with return value 0
Presione una tecla para continuar 
. . . 

List.c

Código PHP:
#include <stdlib.h>
#include "list.h"

list*createList() {
    return 
0;
}
int insertIntoList(list *lst,int posvoid *data){
    return 
0;
}
void*getFromList(list *lstint pos){
    return 
0;
}
int removeFromList(list *lstint pos){
    return 
0;
}
int listLength(list *lst){
    return 
0;
}
void destroyList(list *lst){

List.h
Código PHP:
#ifndef LIST
#define LIST

typedef struct st_nodet{
    
void*data;
    
struct st_node*next;
    
node;

typedef struct{
    
node*first;
    
int length;
} list;

list*
createList();
int inserIntoList(list*lst,int posvoid*data);
void*getFromList(list*lstint pos);
int removeFromList(list*lstint pos);
int listLength(list*lst);
void destroyList(list*lst);
#endif 
main.c

Código PHP:
#include <stdio.h>
#include <stdlib.h>
#include "list.h"
int main(int argcchar *argv[]) {
 list *
lst createList();
 
int i;
 for (
010i++) {
 
insertIntoList(lsti"hola");
 }
 for (
010i++) {
 
printf("item %d: %s\n"i, (char *)getFromList(lsti)); 
 }
 
printf("list length: %d\n"listLength(lst));
 
destroyList(lst);
 return 
0;

  #2 (permalink)  
Antiguo 17/10/2015, 15:05
 
Fecha de Ingreso: febrero-2015
Mensajes: 404
Antigüedad: 9 años, 9 meses
Puntos: 3
Respuesta: Problema con lista enlazada en c

¿En que parte creas o insertas? El único código que tienes en esas funciones es un "return 0" y si lo que tiene que retornar es un puntero 0 es NULL.
  #3 (permalink)  
Antiguo 19/10/2015, 03:54
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 10 años, 2 meses
Puntos: 204
Respuesta: Problema con lista enlazada en c

Cita:
Iniciado por FiniShet Ver Mensaje
El problema que tengo es que no me inserta en la lista me los pone todos en vacio en NULL aunque por lo que veo la lista me la crea y me enseña todo los valores.
Veamos:

Código C:
Ver original
  1. list*createList() {
  2.     return 0;
  3. }

Esa función no crea NUNCA una lista. SIEMPRE va a devolver un puntero nulo, si usas ese puntero para cualquier cosa la aplicación acabará fallando sí o sí.


Código C:
Ver original
  1. int insertIntoList(list *lst,int pos, void *data){
  2.     return 0;
  3. }

Otra función que no hace nada... recibe una lista, seguramente creada a partir de la función anterior, que tampoco hacía nada, por lo que ya empezamos mal, pero es que además esta función NO HACE ABSOLUTAMENTE NADA. No usa los argumentos que recibe y se limita a retornar SIEMPRE 0.

Y con el resto de funciones lo mismo.

Dicho en cristiano, tus deberes son implementar esas funciones... si este código te lo ha pasado alguien como una tarea hecha te puedo asegurar que te ha tomado el pelo... o eso o estás intentando tomarnos tu el pelo a nosotros a ver si cuela y te resolvemos el ejercicio sin tener que mover un dedo... si este es el caso lo siento, no cuela.

Un saludo.

Última edición por eferion; 19/10/2015 a las 03:59
  #4 (permalink)  
Antiguo 19/10/2015, 07:03
 
Fecha de Ingreso: septiembre-2013
Ubicación: Comunidad Valenciana
Mensajes: 4
Antigüedad: 11 años, 3 meses
Puntos: 0
Respuesta: Problema con lista enlazada en c

Perdonen copie el codigo antiguo. PD: si alguien sabe como editar los temas para no volver a escribir mensaje que me diga como
en list.c


*modifique el modo de crear la lista y implemente el código para insertar y ver la lista

Código C:
Ver original
  1. #include <stdlib.h>
  2. #include "list.h"
  3.  
  4. void createList(list *lst) {
  5.     lst->first = NULL;
  6.     lst->length = 0;
  7. }
  8. int insertIntoList(list *lst,int pos, void *data){
  9.    
  10.    
  11.  
  12.   node *actual;
  13.   node *new_data;
  14.  
  15.   int i;
  16.  if((lst = (list*)malloc(sizeof(list)))==NULL)
  17.             return -1;   //creando un espacio de memoria para la lista por si no hay
  18.   if ((new_data = (node *) malloc (sizeof (node))) == NULL)
  19.     return -1;
  20.   if ((new_data->data = (char *) malloc (50 * sizeof (char)))== NULL)
  21.     return -1;
  22.  
  23.   actual = lst->first;
  24.  
  25.   for (i = 1; i < pos; ++i)
  26.     actual = actual->next;
  27.  
  28.   if (actual->next == NULL)
  29.     return -1;
  30.  
  31.   strcpy (new_data->data, data);
  32.   new_data->next = actual->next;
  33.   actual->next = new_data;
  34.   lst->length++;
  35.  
  36.   return 0;
  37.    
  38.  
  39. }
  40. void*getFromList(list *lst, int pos){
  41.     return 0;
  42. }
  43. int removeFromList(list *lst, int pos){
  44.     return 0;
  45. }
  46.  
  47. int listLength(list *lst){
  48.   node *actual;
  49.   actual = lst->first;
  50.  
  51.   while (actual != NULL){
  52.       printf ("%p - %s\n", actual, actual->data);
  53.       actual = actual->next;
  54.    
  55.    
  56. }}
  57. void destroyList(list *lst){
  58.    
  59. }

En la consola no me salta ningun error pero al ejecutarlo falla. Tambien elimine el getfromlist del main.c ya que no tiene funcion todavia
  #5 (permalink)  
Antiguo 19/10/2015, 07:11
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 10 años, 2 meses
Puntos: 204
Respuesta: Problema con lista enlazada en c

Cita:
Iniciado por FiniShet Ver Mensaje
Perdonen copie el codigo antiguo. PD: si alguien sabe como editar los temas para no volver a escribir mensaje que me diga como
en list.c
Solo se puede editar la última respuesta del hilo. Una vez tu mensaje deja de ser el último pierdes toda capacidad para editar el mensaje.

Cita:
Iniciado por FiniShet Ver Mensaje
*modifique el modo de crear la lista y implemente el código para insertar y ver la lista
Vale, ahora solo te falta poner el main. Las funciones de esta nueva versión son diferentes a las iniciales, por lo que el main que tenias inicialmente ya no es válido.

Un saludo.
  #6 (permalink)  
Antiguo 19/10/2015, 07:37
 
Fecha de Ingreso: septiembre-2013
Ubicación: Comunidad Valenciana
Mensajes: 4
Antigüedad: 11 años, 3 meses
Puntos: 0
Respuesta: Problema con lista enlazada en c

En teoría así estaría como las funciones declaradas. solo para ver si de verdad me lo mete en la lista y que lo muestre


Código C:
Ver original
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include "list.h"
  4. int main(int argc, char *argv[]) {
  5.  list *lst;
  6.  
  7. insertIntoList(lst, 0, "hola");
  8. listLength(lst);
  9. return 0;
  10. }
  #7 (permalink)  
Antiguo 19/10/2015, 08:15
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 10 años, 2 meses
Puntos: 204
Respuesta: Problema con lista enlazada en c

Empecemos:

Código C:
Ver original
  1. int insertIntoList(list *lst,int pos, void *data){
  2.   // ...
  3.   if((lst = (list*)malloc(sizeof(list)))==NULL)

Si resulta que la función me crea una lista SIEMPRE... ¿cómo se supone que voy a añadir un segundo elemento a la lista? La segunda vez que llame a la función el segundo elemento lo añadirá en una segunda lista.

lst es un puntero, eso quiere decir que cualquier cambio que realice sobre la memoria a la que apunta se verán reflejados fuera de la función... ahora, si yo modifico la posición de memoria a la que apunta el puntero, dicho cambio es local, por lo que fuera de la función no tendrá efecto.

Código Ejemplo:
Ver original
  1. Si tengo:
  2. list* lista = 0x1000;
  3. insertIntoList(lista,0,algo);
  4.  
  5. entonces lst apuntará a 0x1000 y todos los cambios que realice sobre lst se almacenarán en 0x1000, pero...
  6. si dentro de la función pongo lst=0x2000, todos los cambios que realice a partir de ese momento en lst
  7. se almacenarán en 0x2000. Fuera de la función, lista sigue apuntando a 0x1000, por lo que no podrá ver los
  8. cambios que se han realizado en 0x2000.

Código C:
Ver original
  1. if ((new_data->data = (char *) malloc (50 * sizeof (char)))== NULL)

¿Qué pasa si quiero almacenar una cadena de 100 caracteres? Pasa que voy a pisar memoria que no me pertenece. Este efecto se llama "buffer overflow" y es muy peligroso
¿Qué pasa si quiero almacenar una cadena de 2 caracteres? Estoy desaprovechando un montón de memoria. Por qué no puedes, simplemente, reservar la memoria mínima necesaria para almacenar la cadena? Usa strlen para conocer el tamaño de la cadena y haz una reserva de memoria acorde a esos requisitos (recuerda que necesitas reservar un byte para el caracter nulo de fin de cadena).

Código C:
Ver original
  1. for (i = 1; i < pos; ++i)
  2.     actual = actual->next;

¿Y si pos es mayor que el número de elementos de la lista? Pues sucederá que acabarás pisando memoria que seguramente no te pertenezca y eso provocará que la aplicación te premie con un pantallazo. En sistemas operativos antiguos puedes incluso conseguir bloquear el sistema.

Si tienes lst->length, ¿Por qué motivo no compruebas que pos sea menor que el tamaño de la lista? También puedes optar por comprobar que actual->next no sea NULL antes de pasar al siguiente elemento.

Código C:
Ver original
  1. if (actual->next == NULL)
  2.     return -1;

Al llegar aquí me vienen a la mente unas cuantas dudas:

  • ¿Qué pasa si intento añadir un elemento al final de la lista? Sucederá que actual->next valdrá NULL, por lo que no podré añadir un elemento a la lista...
  • ¿Qué sucede si la lista está vacía? sucederá que actual, que es igual a lst->first vale NULL, ¿qué me devolverá NULL->next?
  • ¿Y si quiero añadir un elemento al inicio de la lista? ¿No se debería modificar lst->first?
  • Después de ese return, la memoria reservada con anterioridad (lst,new_data y new_data->data se pierde. No es que se libere, se queda reservada pero ya no tienes ninguna referencia que te permita llegar hasta a ella, por lo que no puedes liberarla ni hacer nada util con ella. Se dice entonces que tu programa tiene fugas de memoria y ese es un asunto bastante serio. Prueba a llamar a esta función un millón de veces y mira como aumenta el consumo de memoria de tu aplicación... Esto es aplicable a dos de los tres return que tienes antes que este, lo he puesto aquí para no repetirme.


Código C:
Ver original
  1. strcpy (new_data->data, data);

Si resulta que data va a almacenar cadenas de caracteres... ¿por qué no se declara como char* y así ya queda clara su finalidad?
Manipular un puntero genérico void* como si de una cadena se tratase es peligroso porque puede almacenar información binaria, la cual puede contener un número indeterminado de '\0' que forman parte del contenido de la variable.

Código C:
Ver original
  1. int listLength(list *lst){
  2.   node *actual;
  3.   actual = lst->first;
  4.  
  5.   while (actual != NULL){
  6.       printf ("%p - %s\n", actual, actual->data);
  7.       actual = actual->next;
  8. }}

Esto... si yo me encuentro una función con nombre listLength yo esperaría que la función me devolviese el número de elementos de la lista. De primeras esta función no tendría sentido, ya que ya existe un lista->length, pero bueno. Lo que pasa es que esta función no solo no realiza la tarea que aparenta sino que intenta volcar el contenido de la lista en la pantalla. ¿Seguro que esto va aquí?

Por otro lado, si una función tiene un tipo de retorno diferente de void se hace necesario incluir al menos un return. No hay que olvidar que los warning del compilador son en realidad errores, lo que sucede es que estos errores no impiden que el código compile... pero son errores. Son errores que pueden provocar problemas de cualquier tipo, incluso comportamientos erráticos que dependerán del compilador utilizado.

Con esto creo que tienes entretenimiento para un rato :)

Un saludo.

Etiquetas: enlazada, lista
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 03:00.