Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 我的链表代码有什么问题?_C_Linked List - Fatal编程技术网

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);