Ver Mensaje Individual
  #2 (permalink)  
Antiguo 05/09/2012, 07:46
Amphoth3ra
 
Fecha de Ingreso: mayo-2011
Mensajes: 26
Antigüedad: 13 años, 6 meses
Puntos: 1
Respuesta: Segfault con una función que funciona en otro lugar

Me respondo solo ya que corregí por mi cuenta el problema: Usando Valgrind los problemas los detecté en los 2 fcloses de las funciones BuscarCentro y BuscarAlumno.

El programa final quedo así:
Código C:
Ver original
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4.  
  5. struct stAntecedente {
  6.    char rut_alumno[12];
  7.    int id_documento;
  8.    char sentencia[30];
  9.    int id_delito;
  10.    char fecha[12];
  11.    char rut_polichile[12];
  12. };
  13.  
  14. struct stAlumno {
  15.    char rut_alumno[12];
  16.    char nombre[30];
  17.    int edad;
  18.    int id_institucion;
  19. };
  20.  
  21. struct stCentroEduc {
  22.    int id_institucion;
  23.    char nombre[30];
  24. };
  25.  
  26. struct stConteo {
  27.    int cuenta;
  28.    char nombre[30];
  29. };
  30.  
  31. void RevisarConteo()
  32. {
  33.    /* Revisa el ranking archivado
  34.       Se considera como archivo temporal, ya que se genera, se revisa, y posteriormente se elimina. */
  35.    struct stConteo reg_conteo;
  36.    FILE *file_conteo;
  37.    int ranking=1;
  38.    file_conteo = fopen("conteo.dat", "r+b");
  39.    if(!file_conteo)
  40.      file_conteo= fopen("conteo.dat", "w+b");  
  41.  
  42.    while (fread(&reg_conteo, sizeof(struct stConteo), 1, file_conteo) && (ranking <= 5))
  43.    {
  44.    printf("%5d %-30s %12d\n", ranking, reg_conteo.nombre, reg_conteo.cuenta);
  45.    ranking = ranking+1;
  46.    }
  47.  
  48.    printf("\n");
  49.    fclose(file_conteo);
  50. }
  51.  
  52. void InsertarNuevoConteo (char new_nombre[30], int new_count)
  53. {  
  54.    /* El archivo conteo emula un ranking de las instituciones cuyos delitos de sus alumnos más figuran en los
  55.       antecedentes. En otras palabras, el archivo está ordenado por la clave de cuenta en orden decreciente. */
  56.    struct stConteo new_conteo;
  57.    strcpy(new_conteo.nombre, new_nombre);
  58.    new_conteo.cuenta = new_count;
  59.    struct stConteo conteo_temp;
  60.    int insertado = 0;
  61.    FILE *file_conteo, *file_conteotemp;
  62.    file_conteo = fopen("conteo.dat", "r+b");  
  63.    if(!file_conteo)
  64.      file_conteo= fopen("conteo.dat", "w+b");
  65.    file_conteotemp = fopen("conteotemp.dat", "r+b");  
  66.    if(!file_conteotemp)
  67.      file_conteotemp = fopen("conteotemp.dat", "w+b");
  68.  
  69.    while (fread(&conteo_temp, sizeof(struct stConteo), 1, file_conteo))
  70.      {
  71.     if ((new_conteo.cuenta > conteo_temp.cuenta) && insertado==0)
  72.     {
  73.      fwrite(&new_conteo, sizeof(struct stConteo), 1, file_conteotemp);
  74.      fwrite(&conteo_temp, sizeof(struct stConteo), 1, file_conteotemp);
  75.          insertado=1;
  76.     }
  77.     else
  78.     {
  79.      fwrite(&conteo_temp, sizeof(struct stConteo), 1, file_conteotemp);
  80.     }
  81.            
  82.     }
  83.  
  84.     if (insertado==0)
  85.     fwrite(&new_conteo, sizeof(struct stConteo), 1, file_conteotemp);
  86.  
  87.      fclose(file_conteo);
  88.      fclose(file_conteotemp);
  89.  
  90.      remove ("conteo.dat");
  91.      rename ("conteotemp.dat", "conteo.dat");
  92. }
  93.  
  94. void ConteoGeneral (char nombre_institucion[30])
  95. {
  96.   /* Esta función procederá en general a hacer el escrutinio de cada institución de cada alumno
  97.      en el archivo de antecedentes */
  98.   int encontrado = 0;
  99.   int conteo;
  100.   struct stConteo regi;
  101.   FILE *file_conteo, *file_conteotemp;
  102.   file_conteo = fopen("conteo.dat", "r+b");
  103.   if(!file_conteo)
  104.     file_conteo = fopen("conteo.dat", "w+b");
  105.  
  106.    /* Así por cada institución buscamos en el archivo de conteo: */
  107.    while (fread(&regi, sizeof(struct stConteo), 1, file_conteo))
  108.    {    if (!strcmp(regi.nombre, nombre_institucion))
  109.          encontrado = 1;
  110.    }
  111.  
  112.    fclose(file_conteo);
  113.  
  114.    /* Si no está la institución, la insertamos inmediatamente como nueva... */
  115.    if (encontrado==0)
  116.    {
  117.         InsertarNuevoConteo(nombre_institucion, 1);
  118.    }
  119.    
  120.    /* ...pero si está, se debe borrar la institución del archivo original y reinsertarse con su conteo sumado en 1 */
  121.    else
  122.    {
  123.        file_conteo = fopen("conteo.dat", "r+b");
  124.        if(!file_conteo)
  125.      file_conteo = fopen("conteo.dat", "w+b");
  126.        file_conteotemp = fopen("conteotemp.dat", "r+b");
  127.        if(!file_conteotemp)
  128.      file_conteotemp = fopen("conteotemp.dat", "w+b");
  129.  
  130.        while (fread(&regi, sizeof(struct stConteo), 1, file_conteo))
  131.     {  
  132.  
  133.     if (strcmp(nombre_institucion, regi.nombre))
  134.         fwrite(&regi, sizeof(struct stConteo), 1, file_conteotemp);
  135.         else
  136.         conteo = regi.cuenta +1;
  137.        
  138.         }
  139.  
  140.         fclose(file_conteo);
  141.         fclose(file_conteotemp);
  142.  
  143.         remove ("conteo.dat");
  144.         rename ("conteotemp.dat", "conteo.dat");
  145.  
  146.         InsertarNuevoConteo(nombre_institucion, conteo);
  147.    }   
  148.  
  149. }
  150.  
  151. void BuscarCentro (int temp_idinstitucion)
  152. {
  153.    /* Por cada alumno se busca el centro educacional al que pertenece */
  154.    struct stCentroEduc regi;
  155.    FILE *file_cen;
  156.    file_cen = fopen("centros.dat", "r+b");          
  157.    if(!file_cen)
  158.     file_cen = fopen("centros.dat", "w+b");
  159.  
  160.    while (fread(&regi, sizeof(struct stCentroEduc), 1, file_cen))
  161.    {   
  162.     if (temp_idinstitucion==regi.id_institucion)
  163.    
  164.         {
  165.         ConteoGeneral(regi.nombre);    
  166.         }
  167.    }
  168. }
  169.  
  170. void BuscarAlumno (char temp_rutalumno[12])
  171. {
  172.    /* Por cada registro en el archivo de antecedentes busca un alumno */
  173.    struct stAlumno regi;
  174.    FILE *file_alu;
  175.    file_alu = fopen("alumnos.dat", "r+b");          
  176.    if(!file_alu)
  177.     file_alu = fopen("alumnos.dat", "w+b");
  178.  
  179.     while (fread(&regi, sizeof(struct stAlumno), 1, file_alu))
  180.    {   
  181.      if (!strcmp(temp_rutalumno, regi.rut_alumno))
  182.    
  183.         {
  184.         BuscarCentro(regi.id_institucion); 
  185.         }
  186.        
  187.    }  
  188. }
  189.  
  190.  
  191. int main()
  192. {
  193.    /* Función principal: Revisa el archivo de antecedentes */
  194.    struct stAntecedente regi;
  195.    FILE *file_ant;
  196.    file_ant = fopen("antecedentes.dat", "r+b");          
  197.    if(!file_ant)
  198.     file_ant = fopen("antecedentes.dat", "w+b");
  199.    rewind(file_ant);
  200.    printf("Top 5\n");
  201.    printf("----------------------------------------------------\n");
  202.    printf("Lugar Centro Educativo                  N°Delitos\n");
  203.    printf("----------------------------------------------------\n");
  204.    while  (fread(&regi, sizeof(struct stAntecedente), 1, file_ant))
  205.     BuscarAlumno (regi.rut_alumno);;
  206.    RevisarConteo();
  207.    fclose(file_ant);
  208.    remove("conteo.dat");
  209. }

La sugerencia en todo caso la había visto en StackOverflow, pero a pesar de todo la solución la posteo acá por si alguien quiere verlo.

Saludos.