C 我的链表代码有什么问题?
问题已解决:)C 我的链表代码有什么问题?,c,linked-list,C,Linked List,问题已解决:) 我希望你能帮我解释我做错了什么 提前谢谢 代码: #include <stdio.h> #include <stdlib.h> typedef struct node { char *data; struct node * previous; struct node * next; } node, *nodePTR; /* Insert into list */ void insert(char * buf, nodePTR t
我希望你能帮我解释我做错了什么 提前谢谢 代码:
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
char *data;
struct node * previous;
struct node * next;
} node, *nodePTR;
/* Insert into list */
void insert(char * buf, nodePTR tail) {
nodePTR myNode;
myNode = (node *)malloc(sizeof(node));
myNode->data = malloc(sizeof(char) * 10);
strcpy(myNode->data,buf);
myNode->next = NULL;
myNode->previous = tail;
tail->next = myNode;
//tail = tail->next;
}
void printlist(nodePTR head, int numElements) {
nodePTR tmpNode;
tmpNode = head;
printf("\n\n");
while(tmpNode!=NULL) {
printf("Node data: %s\n", tmpNode->data);
tmpNode = tmpNode->next;
}
}
int main(void) {
/* Variables */
int numElements;
int i;
char buf[10];
nodePTR head, tail;
tail = (node *)malloc(sizeof(node));
head = (node *)malloc(sizeof(node));
tail->data = "EMPTY\0";
tail->next = NULL;
tail->previous = NULL;
head = tail;
printf("Please enter the number of elements:\n");
scanf("%d", &numElements);
/* Build the list */
for(i = 0; i < numElements; i++) {
printf("Please enter the data:");
scanf("%s", buf);
insert(buf, tail);
tail = tail->next;
}
printlist(head, numElements);
return 0;
}
#包括
#包括
类型定义结构节点{
字符*数据;
结构节点*previous;
结构节点*下一步;
}node,*nodePTR;
/*插入列表*/
无效插入(字符*buf,节点接受尾部){
nodePTR-myNode;
myNode=(node*)malloc(sizeof(node));
myNode->data=malloc(sizeof(char)*10);
strcpy(myNode->data,buf);
myNode->next=NULL;
myNode->previous=tail;
tail->next=myNode;
//tail=tail->next;
}
无效打印列表(nodePTR head,int numElements){
nodePTR-tmpNode;
tmpNode=头部;
printf(“\n\n”);
while(tmpNode!=NULL){
printf(“节点数据:%s\n”,tmpNode->data);
tmpNode=tmpNode->next;
}
}
内部主(空){
/*变数*/
国际货币基金组织;
int i;
char-buf[10];
头、尾下垂;
tail=(node*)malloc(sizeof(node));
头=(节点*)malloc(节点大小);
tail->data=“EMPTY\0”;
tail->next=NULL;
tail->previous=NULL;
头=尾;
printf(“请输入元素的数量:\n”);
scanf(“%d”和numElements);
/*建立列表*/
对于(i=0;inext;
}
打印列表(标题、数字);
返回0;
}
这是我的输出:请输入元素数:
3
请输入数据:n1
请输入数据:n2
请输入数据:n3
节点数据:空
节点数据:n3
在插入元素之前,我通常会尝试将head和tail保留为NULL,而不是尝试检测整个位置的空节点。其中包括一个我使用的非常简单的链表示例。请注意,此版本适用于微控制器,因此我会在列表功能之外malloc/free内存(有时来自预分配的节点池): 特定于您的代码,当您将对象视为黑盒时,可以避免一些问题,但允许查看内部的函数除外。具体来说,主函数的开头以及第69行直接操作列表成员。我通常会尝试使用一个专用于初始化对象的函数,因为在使用列表时,在许多地方必须再次执行此操作 在第54行,将指向字符串文本的指针推入结构中。此指针仅在当前堆栈帧上有效,这意味着当函数退出时,此指针将不再包含“EMPTY\0”。你应该打电话给malloc并把它储存在那里,别忘了免费。还请注意,C自动null终止字符串文本,因此您不需要在末尾使用\0
最后,它在print函数中不能正确迭代的原因是,您在尾部而不是头部启动了打印迭代器 嗯,我想你的问题是你把所有节点都指向同一个缓冲区。每次都需要复制该缓冲区
myNode->data = buf;
只需将数据指向缓冲区的地址。然后,当您更新该缓冲区时,地址保持不变,但内容会发生变化。所以所有的东西本质上都指向同一个字符串。您需要将缓冲区的内容复制到一个新数组中,并在该数组中指向数据
此外,在循环添加节点时,这一行似乎有问题:
head = head->next;
Insert应该负责这件事
以下是重新编译后的代码:
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
char *data;
struct node * previous;
struct node * next;
} node, *nodePTR;
/* Insert into list */
void insert(char * buf, nodePTR head) {
nodePTR myNode;
myNode = (node *)malloc(sizeof(node));
myNode->data = malloc(sizeof(char) * 10);
strcpy(myNode->data,buf);
myNode->next = head->next;
myNode->previous = head;
head->next = myNode;
}
void printlist(nodePTR head, int numElements) {
nodePTR tmpNode;
tmpNode = head;
printf("\n\n");
while(tmpNode!=NULL) {
printf("Node data: %s\n", tmpNode->data);
tmpNode = tmpNode->next;
}
}
int main(void) {
/* Variables */
int numElements;
int i;
char buf[10];
nodePTR head, tail;
tail = (node *)malloc(sizeof(node));
head = (node *)malloc(sizeof(node));
tail->data = "EMPTY\0";
tail->next = NULL;
tail->previous = NULL;
head = tail;
printf("Please enter the number of elements:\n");
//scanf("%d", &numElements);
numElements=3;
/* Build the list */
for(i = 0; i < numElements; i++) {
printf("Please enter the data:");
buf[0] = 60 + i;
buf[1] = 0;
insert(buf, head);
}
printlist(head, numElements);
return 0;
}
问题是tmpBuf在堆栈上,它仍然指向与buf相同的地址。你需要用malloc分配一个新的缓冲区(或者按照我在评论中的比喻建造一个新房子)
这条线
myNode = (node *)malloc(sizeof(node));
为节点结构中定义的内容创建足够的空间。在您的例子中,它们是指向字符数组、下一个节点和上一个节点的指针。因此,您所拥有的空间就是一个字符数组的地址。实际上,节点中没有空间容纳字符数组
myNode->data = malloc(sizeof(char) * 10);
这个malloc实际上为10个字符的数组腾出了空间,并将数组的地址保存在节点数据字段中。如果没有第二个malloc,您将永远无法为实际阵列腾出空间。当您第一次学习数据结构时,我建议您使用ints作为数据类型。较少的陷阱会让您从所了解的实际数据结构的工作中分心。在此处发布相关代码(不要在链接后面),并描述您所采取的调试步骤以及遇到的问题。最好直接在此处发布代码。我可以建议您尝试通过调试器运行程序吗?如果您使用的是Linux系统,我建议您熟悉GDBI。我已经编辑了我的帖子,其中包含了关于您的版本的更多说明。我的意思是:char[]EmptyStr=“EMPTY”;尾部->数据=(字符*)malloc(strlen(EmptyStr)+1);strcpy(尾部->数据,清空系统);你明白我说的缓冲区吗?buf就像一所房子的地址,可以容纳10封信。所以myNode->data=buf;在数据中存储房屋的地址。然后调用scanf(“%s”,buf);你正在改变谁住在房子里。因此,所有这些节点仍然具有相同房屋的地址。当你去参观打印列表中的房子,看看谁住在那里,你只能找到最近的居民。相反,你需要在每次调用insert和point data时创建一个新的房子。好吧,你的头和尾都有很多事情要做。您可以为两者分配内存,然后将它们分配为相等。如果你还有问题的话,我可以自己再做一点,问一个新问题。除此之外,您可能还需要删除其中一些评论。讨论有点失控了。在将来,尽量避免过多地修改代码。现在我要问的问题是
myNode = (node *)malloc(sizeof(node));
myNode->data = malloc(sizeof(char) * 10);