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

[SOLUCIONADO] El bucle se queda parado (Listas enlazadas)

Estas en el tema de El bucle se queda parado (Listas enlazadas) en el foro de C/C++ en Foros del Web. Buenos días, he tratado por mis propios medios tratar de solucionar este problema, pero no doy con una solución. Trataré de explicarlo. El problema es, ...
  #1 (permalink)  
Antiguo 18/08/2013, 15:29
Avatar de guzzano  
Fecha de Ingreso: julio-2010
Ubicación: Isla de Margarita
Mensajes: 162
Antigüedad: 13 años, 8 meses
Puntos: 13
El bucle se queda parado (Listas enlazadas)

Buenos días, he tratado por mis propios medios tratar de solucionar este problema, pero no doy con una solución. Trataré de explicarlo. El problema es, tengo un bucle que recorre una estructura, hace un parseo con una función y agrega datos, funciona perfecto en una primera llamada que le hago, pero a la segunda, el bucle se queda parado.

La cabecera

Código C:
Ver original
  1. #define PORTS_DIR "/usr/ports/"
  2. #define DB_DIR "/var/lib/pkg/db"
  3.  
  4. struct deppkg
  5. {
  6.   char n_pkg[256];
  7.   char d_pkg[PATH_MAX];
  8.  
  9.   int r_list; /* is read? */
  10.   int i_file; /* in other pkgfile of a pkg is installed? */
  11.  
  12.   struct deppkg * pkgnext;
  13. };
  14.  
  15. struct deppkg * d_firts = NULL;
  16. struct deppkg * d_last = NULL;
  17.  
  18. int
  19. add_dep (const char * n_pkg, const char * d_pkg)
  20. {
  21.   struct deppkg * aux;
  22.  
  23.   aux = malloc(sizeof(struct deppkg));
  24.  
  25.   if (aux == NULL)
  26.     return -1;
  27.  
  28.   aux->pkgnext = NULL;
  29.  
  30.   aux->n_pkg[0] = '\0';
  31.   aux->d_pkg[0] = '\0';
  32.  
  33.   strncat(aux->n_pkg, n_pkg, strlen(n_pkg));
  34.   strncat(aux->d_pkg, d_pkg, strlen(d_pkg));
  35.  
  36.   aux->r_list = 0;
  37.   aux->i_file = 0;
  38.  
  39.   if (d_firts == NULL)
  40.   {
  41.     d_firts = aux;
  42.     d_last = aux;
  43.   }
  44.   else
  45.   {
  46.     d_last->pkgnext = aux;
  47.     d_last = aux;
  48.   }
  49.  
  50.   return 0;
  51. }
  52.  
  53. void
  54. clean_dep ()
  55. {
  56.   struct deppkg * curr = d_firts;
  57.   struct deppkg * aux;
  58.  
  59.   while (curr != NULL)
  60.   {
  61.     aux = curr->pkgnext;
  62.    
  63.     free(curr);
  64.    
  65.     curr = aux;
  66.   }
  67. }
  68.  
  69. int
  70. parse_dep (const char * d_pkg, char *r_pkg, size_t len)
  71. {
  72.   if (d_pkg == 0 || r_pkg == 0 || len <= 0)
  73.     return -1;
  74.  
  75.   char * buffer_next;
  76.   char buffer[3072];
  77.  
  78.   int count = 0;
  79.   static int num_m = 1;
  80.  
  81.   memset(r_pkg, '\0', len);
  82.  
  83.   FILE * pkgfile;
  84.  
  85.   pkgfile = fopen(d_pkg, "r");
  86.  
  87.   if (pkgfile == NULL)
  88.   {
  89.     fprintf(
  90.       stderr,
  91.       "pkgrmd >> Error opening «%s»: %s\n",
  92.       d_pkg,
  93.       strerror(errno)
  94.     );
  95.    
  96.     return -1;
  97.   }
  98.  
  99.   while (fgets(buffer, sizeof(buffer), pkgfile) != NULL)
  100.   {
  101.     if (buffer[0] != '#')
  102.       break;
  103.    
  104.     if (strncmp(buffer, "# Depends on:", 13) == 0)
  105.     {
  106.       buffer_next = strchr(buffer, ':');
  107.       buffer_next += num_m;
  108.      
  109.       while (!isalpha(*buffer_next)) {
  110.         if (*buffer_next == '\0')
  111.           break;
  112.          
  113.         buffer_next++;
  114.         num_m++;
  115.       }
  116.      
  117.       while (*buffer_next != '\0') {
  118.         if (isalpha(*buffer_next) != 0 || isdigit(*buffer_next) != 0
  119.             || *buffer_next == '-')
  120.         {
  121.           r_pkg[count] = *buffer_next;
  122.          
  123.           count++;
  124.         }
  125.        
  126.         if (*buffer_next == ' ' || *buffer_next == ','
  127.             || *buffer_next == '\n')
  128.         {
  129.           fclose(pkgfile);
  130.          
  131.           return 0;
  132.         }
  133.        
  134.         buffer_next++;
  135.         num_m++;
  136.       }
  137.     }
  138.   }
  139.  
  140.   /* Test... */
  141.   num_m = 1;
  142.  
  143.   fclose(pkgfile);
  144.  
  145.   return -1;
  146. }
  147.  
  148. int
  149. pkg_is_installed (const char * n_pkg)
  150. {
  151.   if (strlen(n_pkg) <= 0)
  152.     return -1;
  153.  
  154.   char pkg_fix[254];
  155.   char buffer[256];
  156.  
  157.   int len;
  158.  
  159.   len = snprintf(pkg_fix, sizeof(pkg_fix), "%s\n", n_pkg);
  160.  
  161.   if (len <= 0)
  162.     return -1;
  163.  
  164.   FILE * db;
  165.  
  166.   db = fopen(DB_DIR, "r");
  167.  
  168.   if (db == NULL)
  169.   {
  170.     fprintf(
  171.       stderr,
  172.       "pkgrmd >> Error opening «%s»: %s\n",
  173.       DB_DIR,
  174.       strerror(errno)
  175.     );
  176.    
  177.     return -1;
  178.   }
  179.  
  180.   while (fgets(buffer, sizeof(buffer), db) != NULL)
  181.     if (strcmp(buffer, pkg_fix) == 0) {
  182.       fclose(db);
  183.    
  184.       return 0;
  185.     }
  186.      
  187.    
  188.   fclose(db);
  189.  
  190.   return -1;
  191. }
  192.  
  193. int
  194. pkg_dir_inst (const char * n_pkg, char * d_pkg, size_t len)
  195. {
  196.   if (n_pkg == 0 || len <= 0)
  197.     return -1;
  198.  
  199.   char * verify = NULL;
  200.   char buffer[PATH_MAX];
  201.   int len_s;
  202.  
  203.   DIR * ports_dir;
  204.   struct dirent *dir_s;
  205.  
  206.   ports_dir = opendir(PORTS_DIR);
  207.  
  208.   if (ports_dir == NULL)
  209.   {
  210.     fprintf(
  211.       stderr,
  212.       "pkgrmd >> Error opening «%s»: %s\n",
  213.       PORTS_DIR,
  214.       strerror(errno)
  215.     );
  216.    
  217.     return -1;
  218.   }
  219.  
  220.   while ((dir_s = readdir(ports_dir)) != NULL)
  221.   {
  222.     if (strcmp(dir_s->d_name, ".") == 0) continue;
  223.     else if (strcmp(dir_s->d_name, "..") == 0) continue;
  224.    
  225.     if (dir_s->d_type == DT_DIR) {
  226.        len_s = snprintf(
  227.         buffer,
  228.         sizeof(buffer),
  229.         "%s%s/%s/Pkgfile",
  230.         PORTS_DIR,
  231.         dir_s->d_name,
  232.         n_pkg
  233.        );
  234.      
  235.       if (len_s <= 0)
  236.         return -1;
  237.      
  238.       if (access(buffer, F_OK) != -1) {
  239.         verify = strncpy(d_pkg, buffer, len);
  240.         break;
  241.       }
  242.     }
  243.   }
  244.  
  245.   if (verify == NULL)
  246.   {
  247.     closedir(ports_dir);
  248.    
  249.     return -1;
  250.   }
  251.    
  252.   closedir(ports_dir);
  253.  
  254.   return 0;
  255. }

El cuerpo

Código C:
Ver original
  1. #include <string.h>
  2. #include <stdio.h>
  3. #include <dirent.h>
  4. #include <errno.h>
  5. #include <ctype.h>  
  6. #include <unistd.h>
  7. #include <stdlib.h>
  8.  
  9. #include "pkgrmd.h"
  10.  
  11. int main (int argc, char * argv[])
  12. {
  13.   if (argc > 1)
  14.   {
  15.     char d_pkg[PATH_MAX] = {0};
  16.     char n_pkg[255] = {0};
  17.    
  18.     char r_pkg[255] = {0};
  19.     char d_pkg_buff[PATH_MAX] = {0};
  20.        
  21.     strncat(n_pkg, argv[1], sizeof(n_pkg)-1);
  22.    
  23.     if (pkg_is_installed(n_pkg) != 0)
  24.     {
  25.       fprintf(stderr, "pkgrmd >> This package is not installed\n");
  26.  
  27.       return EXIT_FAILURE;
  28.      }
  29.      
  30.     if (pkg_dir_inst(n_pkg, d_pkg, sizeof(d_pkg)) != 0)
  31.     {
  32.       fprintf(stderr,"pkgrmd >> An error was encountered\n");
  33.      
  34.       return EXIT_FAILURE;
  35.     }
  36.    
  37.     while (parse_dep(d_pkg, r_pkg, sizeof(r_pkg)) != -1)
  38.     {  
  39.       if (pkg_dir_inst(r_pkg, d_pkg_buff, sizeof(d_pkg_buff)) != 0)
  40.         continue;
  41.        
  42.       if (add_dep(r_pkg, d_pkg_buff) != 0)
  43.         continue;
  44.     }
  45.    
  46.     /* Has two structures, the first is NULL if not have data  */
  47.     if (d_firts == NULL)
  48.     {
  49.       fprintf(stderr,
  50.       "pkgrmd >> The package %s not have depends.\n", n_pkg);
  51.  
  52.       return EXIT_FAILURE;
  53.     }
  54.    
  55.     struct deppkg * aux = d_firts;
  56.    
  57.     while (aux != NULL)
  58.     {
  59.       if (aux->r_list != 0)
  60.         continue;
  61.      
  62.       if (pkg_dir_inst(aux->n_pkg,
  63.             d_pkg_buff,
  64.             sizeof(d_pkg_buff)) != 0)
  65.         continue;
  66.      
  67.       while (parse_dep(d_pkg_buff, r_pkg, sizeof(r_pkg)) != -1)
  68.       {
  69.         // Aquí...
  70.         add_dep(r_pkg, "tes"t);
  71.      
  72.       }
  73.      
  74.       // Luego de arriba, aquí no se ejecuta.
  75.  
  76.       aux = aux->pkgnext;
  77.     }
  78.    
  79.     clean_dep();
  80.   }
  81.   else
  82.   {
  83.     fprintf(
  84.       stderr,
  85.       "pkgrmd >> syntax: pkgrmd <name_package>\n"
  86.     );
  87.   }
  88.  
  89.   return 0;
  90. }

Donde dice 'aquí' es la parte que donde se queda parado aún así el bucle haya terminado.

Muchas gracias, y espero sus respuestas. :)
  #2 (permalink)  
Antiguo 19/08/2013, 08:41
Avatar de L3m0n  
Fecha de Ingreso: diciembre-2011
Mensajes: 219
Antigüedad: 12 años, 3 meses
Puntos: 46
Respuesta: El bucle se queda parado (Listas enlazadas)

No me he mirado el codigo muy a fondo, pero hay una tontería que podría ser el causante de todo.
Cuando llamas a la funcion add_dep, el segundo argumento es "tes"t y supongo que debería ser "test". Puede que eso sea lo que se carga el bucle.
  #3 (permalink)  
Antiguo 19/08/2013, 09:29
Avatar de guzzano  
Fecha de Ingreso: julio-2010
Ubicación: Isla de Margarita
Mensajes: 162
Antigüedad: 13 años, 8 meses
Puntos: 13
Respuesta: El bucle se queda parado (Listas enlazadas)

Gracias por tu respuesta. Eso fue un error al traspasar el código al foro, en el archivo donde compilo está bien.

Edito: Creo encontrar el problema, doy la solución por si alguien algún día se topa con este error. Volví a reprogramar y me di cuenta que estaba haciendo varios continue en un bucle que recorría una estructura dinámica, al esas condiciones ser falsas, hacía que el bucle fuera infinito ya que no estaba dando otra dirección en la memoria donde buscar.

Código C:
Ver original
  1. struct list {
  2.   ...
  3.   struct list * next;
  4. } ...
  5.  
  6. while (aux != NULL) {
  7.   // No es lo mismo, esto
  8.   if (...)
  9.     continue;
  10.  
  11.   // A esto
  12.   if (...) {
  13.     aux = aux->next;
  14.     continue
  15.   }
  16.  
  17.   aux = aux->next;
  18. }

Muchas gracias igual,
Saludos

Última edición por guzzano; 20/08/2013 a las 09:03

Etiquetas: bucle, funcion, int, listas, queda, string, struct
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 07:20.