无限循环链表

时间:2012-04-19 21:27:39

标签: c linked-list structure infinite-loop

似乎就在我的代码中我有一个无限循环打印出相同的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;
    }
}

}

带有typedef的头文件:

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;

1 个答案:

答案 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));
    /* ... */