为什么这段C代码会陷入无限循环?

发布于 12-26 01:59 字数 780 浏览 4 评论 0原文

我一直在尝试修复这段代码中的无限循环。但是,我无法理解为什么会发生无限循环。此代码尝试在处理之前对作业进行从小到大的排序。

SortJobs()
{
    linked_list ptr, h, temp, pptr;
    int i, j;

    pptr = ready_queue;
    ptr = ready_queue->next;
    h= ready_queue;

    while(ptr != NULL) {    
        if ((ready_queue->pcb.job_length - ready_queue->pcb.run_time) > (ptr->pcb.job_length - ptr->pcb.run_time)) {
            ready_queue = ptr;
            pptr->next = ptr->next;
            ptr->next = h->next;                
            h->next = pptr->next;
            pptr->next = h;
            ptr=h->next;
            h=ready_queue;
            pptr=ptr->next;
        } else {
            pptr = ptr;
            ptr=ptr->next;          
        }
    }
}

I have been trying to fix the infinite loop in this code. However, I could not understand why an infinite loop occurs. This code is trying to sort jobs from the smallest to highest before being processed.

SortJobs()
{
    linked_list ptr, h, temp, pptr;
    int i, j;

    pptr = ready_queue;
    ptr = ready_queue->next;
    h= ready_queue;

    while(ptr != NULL) {    
        if ((ready_queue->pcb.job_length - ready_queue->pcb.run_time) > (ptr->pcb.job_length - ptr->pcb.run_time)) {
            ready_queue = ptr;
            pptr->next = ptr->next;
            ptr->next = h->next;                
            h->next = pptr->next;
            pptr->next = h;
            ptr=h->next;
            h=ready_queue;
            pptr=ptr->next;
        } else {
            pptr = ptr;
            ptr=ptr->next;          
        }
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

不再让梦枯萎2025-01-02 01:59:39

gdb 是调试此类问题的朋友。请开始使用调试器!

OTOH,这是一个循环(链接)列表吗?!

提示:在运行 SortJobs() 之前,您可以运行 ready_queue 并打印所有元素并查看它是否进入无限循环吗?!

无限循环的原因可能是因为您没有将链接列表中的最后一个节点设置为NULL。您可以检查您的 addNode() 函数。

gdb is your friend for debugging such issues. Please start using debuggers!

OTOH, is this a circular-(linked)-list?!

TIP: before running SortJobs(), can you run through your ready_queue and print all the elements and see whether it goes in an infinite loop?!

The reason for an infinite loop could be because you haven't set the last node in your linked-list to NULL. You can check your addNode() function.

因为 ptr 总是不为空?

Because ptr always is not null??

热情消退2025-01-02 01:59:39

突出的问题是,此行:

    pptr=ptr->next;

有时可能会跟随此行:

    pptr->next = ptr->next;

之间没有对 pptrptr 进行任何更改。这将产生一个小的单节点循环链表,其中 ptr->next->next == ptr->next。所以你永远无法跳出链表。

总的来说,我发现你的算法非常混乱。您确实需要为每个变量确定一个逻辑含义,并提出适当的循环不变量。例如,在循环迭代结束时,有时会出现 ptr == pptr->next (我认为这是正确的),但有时会出现 pptr == ptr ->next (由于上面给出的原因,我很确定这是错误的)。

The problem that stands out is that this line:

    pptr=ptr->next;

can sometimes be followed by this line:

    pptr->next = ptr->next;

with no changes to pptr or ptr in between. This will result in a little one-node circular linked list, with ptr->next->next == ptr->next. So you can never get out of the linked list.

Overall, I find your algorithm very confusing. You really need to decide on a single logical meaning for each variable, and come up with appropriate loop invariants. For example, at the end of a loop iteration, you'll sometimes have ptr == pptr->next (which, I think, is correct), but sometimes pptr == ptr->next (which I'm pretty sure is wrong, for the reason given above).

末が日狂欢2025-01-02 01:59:39

我发现你的算法非常令人困惑,而且我认为它也是错误的。假设循环以某种方式结束,并且您所做的一切都正确,您将得到的结果是第一个元素是具有最小 job_length - run_time 的元素,但列表的其余部分不会被排序。

正如鲁阿赫指出的那样,问题是当你摆弄所有下一个指针时,你弄乱了你的列表,你把事情变得过于复杂了!我不会触及列表本身的结构来移动整个节点,而是使用 memcpy 并仅移动节点携带的数据。这是一个示例函数:

// I assume your linked list is made of nodes such as this
typedef struct {
    struct Node next;
    struct Node prev;     // optional
    struct Somewhat pcb;
} Node;

void swapData(Node *n1, Node *n2)
{
    struct pcb temp;

    memcpy(&temp, n1->pcb, sizeof(struct Somewhat));
    memcpy(n1->pcb, n2->pcb, sizeof(struct Somewhat));
    memcpy(n2->pcb, &temp, sizeof(struct Somewhat));
}

现在我们能够正确交换节点,我将使用一些经过充分测试/众所周知的排序算法,这样您会更容易找到帮助,并且下一个查看您代码的人会获胜不要试图自杀(无意冒犯,我只是开玩笑;))。让我建议一些简单的算法,例如 选择排序冒泡排序。不是很快但很容易实现:)

I find your algorithm very confusing and I think it is also wrong. Supposing the loop ends somehow and you did everything right the result you'll get is that the first element is the one with the minimum job_length - run_time, but the rest of the list won't be ordered.

As ruakh pointed out, the problem is that you mess up your list when fiddling with all the next pointer, you're overcomplicating things! I wouldn't touch the structure of the list itself moving entire nodes around, rather use memcpy and move only the data carried by the nodes. Here's a sample funcion:

// I assume your linked list is made of nodes such as this
typedef struct {
    struct Node next;
    struct Node prev;     // optional
    struct Somewhat pcb;
} Node;

void swapData(Node *n1, Node *n2)
{
    struct pcb temp;

    memcpy(&temp, n1->pcb, sizeof(struct Somewhat));
    memcpy(n1->pcb, n2->pcb, sizeof(struct Somewhat));
    memcpy(n2->pcb, &temp, sizeof(struct Somewhat));
}

Now that we're able to swap correctly nodes, I'd use some well-tested/well-known sorting algorithm, this way you'll find help easier and the next one who will look at your code won't be tempted to kill himself (no offence intended, I'm just kidding ;) ). Let me suggest some simple algorithm such as the Selection sort or the Bubble sort. Not very fast but easy to implement :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文