簡體   English   中英

無限循環鏈表

[英]Infinite loop linked list

似乎在我的代碼中,盡管試圖將變量向前移動到下一個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;
    }
}

}

具有typedefs的頭文件:

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;

這是一個非常微妙的錯誤:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM