C链接列表卡游戏,由于致命的bug导致奇怪的结果(C Linked list card game and getting weird results due to fatal bug)

编程入门 行业动态 更新时间:2024-10-25 10:22:47
C链接列表卡游戏,由于致命的bug导致奇怪的结果(C Linked list card game and getting weird results due to fatal bug)

我很擅长使用C编码(因此我正在进行愚蠢的练习)。 该代码应该创建一个链接列表,模拟手中持有的一副牌。

该代码旨在:(1)取出第一张卡片并将其放在桌子上,然后(2)取出新的第一张卡片并将其放在手持的卡片的末端。

非常奇怪的是,我的代码在前几次迭代中运行良好,然后突然开始在屏幕上无休止地打印。 不幸的是,我对C的了解还不足以理解bug是什么。 我尝试过不同的代码变体,似乎没什么用。

我非常感谢您的意见。 我附上了我的代码并打印出来。 我还强调了打印到屏幕的功能。 我猜测问题在于add_to_desk()函数。

码:

#include <stdio.h> #include <stdlib.h> typedef struct Node { int data; struct Node* next; } *Node_t; void print_list(Node_t root) { while (root != NULL) { printf("%d ", root->data); root = root->next; } printf("\n"); } Node_t first_to_last(Node_t root, Node_t head){ Node_t next_root, last_root; // get the pointer to the second element next_root = root->next; // unlink first element root->next = NULL; // rename first element to last last_root = root; // reassign root to former second root root = next_root; // designate new root as head head = root; while (root != NULL) { if (root->next == NULL) { root->next = last_root; break; } root = root->next; } return head; } int delete_first(Node_t *head){ Node_t temp = (*head); // get data to be returned int val = (*head)->data; // reassign head to the second element *head = (*head)->next; // unlink former first element temp->next = NULL; return val; } void add_to_desk(Node_t *desk, Node_t temp){ // check if desk is empty if ((*desk) == NULL) { // insert first element (*desk) = temp; } else { temp->next = (*desk); (*desk) = temp; //*desk = temp; } } int main(){ //initialize variables int val; int i; Node_t root, head; // set size of list of cards int n = 4; // allocate memory for temp list Node_t temp = malloc(sizeof(struct Node)); temp->data = 0; temp->next = NULL; // allocate memory for desk cards Node_t desk = malloc(sizeof(struct Node)); desk->data = 0; desk->next = NULL; // allocate memory for list of cards Node_t list = malloc(sizeof(struct Node) * n); // initalize list with n cards for (i=0; i < n; i++) { list[i].data = i+1; if (i == n-1) { list[i].next = NULL; } else { list[i].next = &list[i+1]; } } printf("\nWe start with these cards in our hand: "); root = &(list[0]); print_list(root); while (1){ while (root != NULL){ val = delete_first(&root); printf("We have removed the first card of our hand, val = %d\n",val); printf("New list: "); print_list(root); printf("Lets add val %d to the stack on the desk\n",val); if (desk->data == 0) { printf("First time adding to desk stack\n"); desk->data = val; desk->next = NULL; } else { temp->data = val; printf("Adding val %d to desk stack\n",val); add_to_desk(&desk,temp); } printf("New desk stack: "); print_list(desk); if (root->next == NULL) { printf("We are at the last card of our hand, just throw it on the desk\n"); temp->data = root->data; add_to_desk(&desk,temp); print_list(desk); // <--- HERE'S WHERE PRINTING GOES OUT OF CONTROL break; } else { head = first_to_last(root, head); root = head; printf("We have just moved the first card of our hand to the end\n"); printf("New hand order: "); print_list(root); } } return 1; } }

打印:

Running… We start with these cards in our hand: 1 2 3 4 We have removed the first card of our hand, val = 1 New list: 2 3 4 Lets add val 1 to the stack on the desk First time adding to desk stack New desk stack: 1 We have just moved the first card of our hand to the end New hand order: 3 4 2 We have removed the first card of our hand, val = 3 New list: 4 2 Lets add val 3 to the stack on the desk Adding val 3 to desk stack New desk stack: 3 1 We have just moved the first card of our hand to the end New hand order: 2 4 We have removed the first card of our hand, val = 2 New list: 4 Lets add val 2 to the stack on the desk Adding val 2 to desk stack New desk stack: 2 2 2 2 2 2 2 2 ...... 2's forever

I'm very new to coding in C (and therefore the silly exercise I am working on). The code is supposed to create a linked list that simulates a deck of cards being held in hand.

The code is meant to: (1) remove the first card and place it on the table, then (2) take the new first card and place it at the end of the deck held in hand.

What is very weird is that my codes works well for the first few iterations, then suddenly it starts endlessly printing on the screen. Unfortunately my knowledge of C is not good enough to understand what the bug is. I've tried different variations of code and nothing seems to work.

I would greatly appreciate your input. I've attached my code and the print out. I have also highlighted the function that prints to screen. I'm guessing the problem is with the function add_to_desk().

Code:

#include <stdio.h> #include <stdlib.h> typedef struct Node { int data; struct Node* next; } *Node_t; void print_list(Node_t root) { while (root != NULL) { printf("%d ", root->data); root = root->next; } printf("\n"); } Node_t first_to_last(Node_t root, Node_t head){ Node_t next_root, last_root; // get the pointer to the second element next_root = root->next; // unlink first element root->next = NULL; // rename first element to last last_root = root; // reassign root to former second root root = next_root; // designate new root as head head = root; while (root != NULL) { if (root->next == NULL) { root->next = last_root; break; } root = root->next; } return head; } int delete_first(Node_t *head){ Node_t temp = (*head); // get data to be returned int val = (*head)->data; // reassign head to the second element *head = (*head)->next; // unlink former first element temp->next = NULL; return val; } void add_to_desk(Node_t *desk, Node_t temp){ // check if desk is empty if ((*desk) == NULL) { // insert first element (*desk) = temp; } else { temp->next = (*desk); (*desk) = temp; //*desk = temp; } } int main(){ //initialize variables int val; int i; Node_t root, head; // set size of list of cards int n = 4; // allocate memory for temp list Node_t temp = malloc(sizeof(struct Node)); temp->data = 0; temp->next = NULL; // allocate memory for desk cards Node_t desk = malloc(sizeof(struct Node)); desk->data = 0; desk->next = NULL; // allocate memory for list of cards Node_t list = malloc(sizeof(struct Node) * n); // initalize list with n cards for (i=0; i < n; i++) { list[i].data = i+1; if (i == n-1) { list[i].next = NULL; } else { list[i].next = &list[i+1]; } } printf("\nWe start with these cards in our hand: "); root = &(list[0]); print_list(root); while (1){ while (root != NULL){ val = delete_first(&root); printf("We have removed the first card of our hand, val = %d\n",val); printf("New list: "); print_list(root); printf("Lets add val %d to the stack on the desk\n",val); if (desk->data == 0) { printf("First time adding to desk stack\n"); desk->data = val; desk->next = NULL; } else { temp->data = val; printf("Adding val %d to desk stack\n",val); add_to_desk(&desk,temp); } printf("New desk stack: "); print_list(desk); if (root->next == NULL) { printf("We are at the last card of our hand, just throw it on the desk\n"); temp->data = root->data; add_to_desk(&desk,temp); print_list(desk); // <--- HERE'S WHERE PRINTING GOES OUT OF CONTROL break; } else { head = first_to_last(root, head); root = head; printf("We have just moved the first card of our hand to the end\n"); printf("New hand order: "); print_list(root); } } return 1; } }

Print out:

Running… We start with these cards in our hand: 1 2 3 4 We have removed the first card of our hand, val = 1 New list: 2 3 4 Lets add val 1 to the stack on the desk First time adding to desk stack New desk stack: 1 We have just moved the first card of our hand to the end New hand order: 3 4 2 We have removed the first card of our hand, val = 3 New list: 4 2 Lets add val 3 to the stack on the desk Adding val 3 to desk stack New desk stack: 3 1 We have just moved the first card of our hand to the end New hand order: 2 4 We have removed the first card of our hand, val = 2 New list: 4 Lets add val 2 to the stack on the desk Adding val 2 to desk stack New desk stack: 2 2 2 2 2 2 2 2 ...... 2's forever

最满意答案

问题是你只需要分配一次temp ,然后每次将卡添加到desk时重复使用它。

第一次将卡放在桌面上时没有问题 - 您只需在malloc'd节点中设置值并将其分配给变量desk 。

第二次通过,已分配桌面,因此您在malloc'd节点中设置值并将其分配给变量temp ,并更新desk以使其指向该节点。

第三次通过是麻烦开始的地方。 您将temp的值设置为2,但该temp仍然是您上次使用的对象(它仍然是桌面的顶部。)您还将其next指针更新为指向desk - 这仍然是您最初malloc'd并分配给temp同一节点。

换句话说, temp和desk最终指向内存中指向自身的同一节点。 试图打印这个只是意味着一遍又一遍地访问同一张卡片,这也意味着你永远不会达到空值,所以你永远不会停止。

The problem is that you only allocate temp once, and then reuse it every time you add a card to the desk.

The first time you put a card on the desk there's no problem - you just set the value in the node you malloc'd and assigned to the variable desk.

Second time through, desk has been assigned, so you set the value in the node you malloc'd and assigned to variable temp, and update desk so that it points to that node.

The third time through is where the trouble starts. You set the value of temp to 2, but that temp is still the same object that you used last time (it's still the top of the desk.) You also update its next pointer to point to desk - which, again, is still the same node you originally malloc'd and assigned to temp.

In other words, temp and desk end up pointing to the same node in memory, which is pointing to itself. Trying to print this just means visiting the same card over and over again, which also means you never reach a null value, so you never stop.

更多推荐

本文发布于:2023-04-29 05:43:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1335252.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:奇怪   链接   列表   游戏   Linked

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!