Программа всегда падает при создании связанного списка из файла - PullRequest
0 голосов
/ 14 мая 2019

Я пытаюсь написать программу для помещения первой записи (записи разделяются символом /) каждой строки файла в связанный список, но, к сожалению, я не могу этого сделать.

Первый цикл while работает хорошо, но после этого он полностью падает. Я пробовал несколько подходов, но ни один не работал до сих пор. Буду признателен за любую помощь, потому что я очень подчеркиваю, что не могу сделать что-то такое простое

спасибо заранее!

t_local *cria_cabecalhoL(void){
    t_local *lista = (t_local*)malloc(sizeof(t_local));
    if (lista != NULL)
        lista->next = NULL;
    return lista;
}
typedef struct local{
    char *name;
    struct local *next;

}t_local;


void createlistlocals(t_local *header_l){
    FILE *fp;
    t_local *aux;
    t_local *aux1;
    aux1 = header_l;
    char *line = malloc(150*sizeof(char));
    char *name1 = malloc(150*sizeof(char));
    char c;
    fp = fopen("locais.txt","r");
    fgets(linha, 150, fp);
    while (strcmp(line, "end")!=0){
        puts(line);
        name =strtok(line, "/");
        puts(name1);
        aux->name = strdup(name1);
        aux->next = aux1->next;
        aux1->next= aux;
        aux1 = aux;
        fgets(line, 150, fp);
    }
    aux1 = header_l;

}


int main()
{
    t_local *header_l = cria_cabecalhoL();
    createlistlocals(header_l);

}

Ответы [ 2 ]

0 голосов
/ 14 мая 2019

Глядя на этот цикл, кажется, есть пара ошибок.

  • Вы создаете один головной узел, но затем не выделяете дополнительную память для каждой из строк во время чтения
  • Кажется, что в первой итерации используется неинициализированный указатель (возможно, сбой или повреждение памяти).
  • В следующей итерации используется нулевой указатель (почти наверняка, сбой).

Обозначая цикл, который у вас был:

void createlistlocals(t_local *header_l){
    FILE *fp;
    t_local *aux;
    t_local *aux1;
    aux1 = header_l; // aux1 = head, aux is uninitialised
    char *line = malloc(150*sizeof(char)); // needs to be freed at the end
    char *name1 = malloc(150*sizeof(char));
    char c;

    fp = fopen("locais.txt","r");
    fgets(line, 150, fp); // assumuming linha == line

    // Note, there are ways to loop until the actual file end rather thna a "special line"
    while (strcmp(line, "end")!=0){ 
        puts(line);
        name1 =strtok(line, "/"); // Assuming the rest of the line is not important.
        puts(name1);

        // aux was uninitialised, so this will be undefined behaviour and either crash or
        // overwrite something (memory corruption) that may cause strange things later
        // (including crashes)
        aux->name = strdup(name1);
        // cria_cabecalhoL set header_l->next to null, so this is not actually creating a new node.
        // and the next loop will actually try to use null->name and that is basically garunteed
        // to crash on most systems.
        aux->next = aux1->next;

        aux1->next= aux;
        aux1 = aux;
        fgets(line, 150, fp); // This is duplicate, could be once at the start of the loop, maybe use for(...) loop
    }
    aux1 = header_l; // Note, assigning a local here at the end doesn't do anything

}

Исправление ошибок, связанных со связанным списком, и допущение, что t_local->name == NULL является значением вашего конечного стража.

t_local *cria_cabecalhoL(void){
    t_local *lista = (t_local*)malloc(sizeof(t_local));
    if (lista != NULL)
        lista->name = NULL; // no data, empty node
        lista->next = NULL;
    return lista;
}
void createlistlocals(t_local *header_l){
    FILE *fp;
    t_local *node = header_1;
    t_local *next;
    char *line = malloc(150*sizeof(char)); // needs to be freed at the end
    char *name1;

    fp = fopen("locais.txt","r");
    fgets(line, 150, fp);

    while (strcmp(line, "end")!=0){ 
        puts(line);
        name1 =strtok(line, "/");
        puts(name1);

        node->name = strdup(name1);
        // And create a new empty node for the next loop
        next = cria_cabecalhoL();
        node->next = next; // New node comes after the current one.
        node = next; // And now using the next node on loop

        fgets(line, 150, fp);
    }
}
0 голосов
/ 14 мая 2019

Хорошо, вот грубая попытка исправить наиболее очевидные проблемы со структурой.

t_local * createlistlocals(const char *filename)
{
    FILE * const fp = fpoen(filename, "rt");
    if (fp == NULL)
     return NULL;
    t_local *head = NULL;
    char line[150];
    while (fgets(line, sizeof line, fp) != NULL)
    {
      const char * const slash = strchr(line, '/');
      if (slash == NULL)
        break;
      t_local * const node = malloc(sizeof *node);
      if (prev != NULL)
      {
        prev->next = node;
      }
      else
      {
        head = node;
      }
      *slash = '\0';
      node->name = strdup(line);
      prev = node;
    }
    fclose(fp);
    return head;
}

это также обрабатывает любую несоответствующую линию (например, строку без косой черты) как конечный маркер. Это будет включать end.

Как и любой код, который выполняет операции ввода-вывода и выделения памяти, его можно сделать более надежным. :)

Возвращает список с данными первой строки в первом узле и т. Д. И принимает имя файла вместо жесткого кодирования имени файла и принятия исходного узла списка. Это более понятно и полезно для меня.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...