1

似乎在我的代码中,我有一个无限循环打印出同一个名为 search 的 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;
4

1 回答 1

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节点(即 with 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));
    /* ... */
于 2012-04-19T23:07:07.880 回答