2012-04-19 2 views
1

Кажется, что здесь, в моем коде, у меня есть бесконечный цикл печати той же переменной class_t, называемой поиском, несмотря на попытку переместить переменную в следующую class_t. Все структуры class_t либо указывают на (class_t *) 0 (потому что я получил предупреждения компилятора, если я использовал NULL, потому что я сравнивал class_t * и void *) или указывал на следующую соответствующую структуру class_t. Что я делаю неправильно, или я должен искать где-то еще для моей проблемы?Связанный список бесконечной петли

class_t *search = (students + i)->class_p;//students is a seperate structure where class_p is a pointer to a class_t structure 
      while(search != (class_t*)0) 
      { 
        fprintf(output,": %s%d %d %d\n", search->name, search->number, search->section, search->credits); 
        search = search->nextClass; 
      } 

Вот пример вывода, и, глядя на него, это последнее чтение в class_t из файла

: CS521 1 4 
: CS521 1 4 
: CS521 1 4 
: CS521 1 4 
: CS521 1 4 
: CS521 1 4 
: CS521 1 4 
: CS521 1 4 
: CS521 1 4 
: CS521 1 4 
: CS521 1 4 
: CS521 1 4 

А вот создание class_t:

class_t newClass; 
newClass.number = classid; 
newClass.section = section; 
newClass.credits = credits; 
newClass.nextClass = (class_t*)0; 

И когда добавлен узел:

void addNode(student_t students[], class_t addClass, int ref) 
{ 
int found = 0; 

if((students + ref)->class_p == (class_t*)0)//no classes yet 
{ 
    (students + ref)->class_p = &addClass; 
    found = 1; 
} 
else if((*((students + ref)->class_p)).number > addClass.number && found == 0)//checks first class 
{ 
    class_t *temp = (students + ref)->class_p; 
    (students + ref)->class_p = &addClass; 
    addClass.nextClass = temp; 
    found = 1; 
} 
else//works way through the class linked list to find where it goes 
{ 
    class_t *beforesearch = (students + ref)->class_p; 
    class_t *search = beforesearch->nextClass; 
    while(search != (class_t*)0 && found == 0) 
    { 
     if(search->number < addClass.number) 
     { 
      beforesearch->nextClass = &addClass; 
      addClass.nextClass = search; 
      found = 1; 
     } 
     else 
     { 
      beforesearch = search; 
      search = search->nextClass; 
     } 
    } 

    if(found == 0) 
    { 
     beforesearch->nextClass = &addClass; 
     found = 1; 
    } 
} 

}

Header файлы с: определений типов

typedef struct class_t { 
char name[3]; 
int number; 
int section; 
int credits; 
struct class_t *nextClass; 
} class_t; 

typedef struct student_t { 
int id; 
class_t *class_p; 
} student_t; 
+2

Возможно, у вашего списка есть петля? – SLaks

+0

Я бы оценил, как вы обрабатываете голову/хвост при добавлении/удалении узлов. Вероятно, вы вводите цикл. – Thomas

+0

Вам нужно посмотреть, как вы создали список. В нем есть петля! –

ответ

1

Это очень тонкая ошибка:

void addNode(student_t students[], class_t addClass, int ref) 
{ 
    int found = 0; 

    if((students + ref)->class_p == (class_t*)0)//no classes yet 
    { 
     (students + ref)->class_p = &addClass; 

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

Если вы получаете цикл списка, вы попали в случай, когда каждый вызов addNode копирует структуру в тот же адрес в стеке. Но это много удачи, есть так много вещей, которые могут пойти не так с этим кодом, что я не буду их объяснять.

Правильное решение состоит в том, чтобы выделить class_t узлы в куче (то есть с malloc()) и передать указатель на них. Или еще выделите копию до ссылки:

void addNode(student_t students[], class_t addClass_param, int ref) 
{ 
    class_t *addClass = malloc(sizeof(class_t)); /* Check for NULL return skipped */ 
    memcpy(addClass, &addClass_param, sizeof(class_t)); 
    /* ... */ 
+0

Да, это то, что я сказал в комментариях. Но есть еще ... – wildplasser

+0

Я принял ваше предложение, но это не имело значения. Я дал ему место на куче, а также удостоверился, что все было скопировано на новое место. Однако теперь он ничего не выводит в выходной файл и все еще зацикливается в каком-то цикле. – Setzra

+0

@Setzra: Это такая ситуация, когда отладчик подходит. – C2H5OH

Смежные вопросы