首页 > 解决方案 > 打印链表总是打印最后一个节点

问题描述

我目前正在做一个项目,我需要在链表的末尾添加一个节点(这应该很容易让我发疯)。问题是当我尝试打印完整的链表时,我会重复获取最后一个节点的数据。我的代码:

struct page *add_page (struct page *web, char *url){
    struct page *newNode = (struct page*) malloc(1*sizeof(struct page));
    newNode->url = url;
    newNode->next = NULL;
    
    if(web == NULL){
        web = newNode;
    }else{
        struct page *curr = web;
        while(curr->next != NULL){
            if(newNode->url==curr->url){
                printf("URL \"%s\" is already on the web\n",newNode->url);
                return web;
                free(newNode);
            }else{
                curr = curr->next;
            }
        }
        curr->next = newNode;
    }
    return web;
    free(newNode);
}

我确定问题出在此功能上。我尝试了其他方法,但这是我能得到的最好的。提前致谢。

标签: clinked-listnodes

解决方案


您可能在多次调用中使用相同的 char 指针,add_page并且只在调用之间更改它指向的内容。这意味着您只有一个 char 指针,它被您创建的所有节点共享。对存储在那里的字符串的任何更改都将是所有节点指向的字符串。

您应该更改调用代码,以便它创建一个新字符串而不是改变现有字符串,或者确保该函数获取所提供字符串的副本。url由于您没有提供调用代码,我将选择第二种解决方案。

其他一些问题:

  • 您不应该比较 char 指针来检测重复节点,而是使用strcmp.
  • 您的return语句后面有死代码。在第一种情况下,free调用应该发生在语句之前return。然而,finalfree在这个函数中没有意义。这应该稍后发生,当您想要删除一个节点或整个树时,而不是在这个函数中。
struct page *add_page (struct page *web, char *url) {
    struct page *newNode = (struct page*) malloc(1*sizeof(struct page));
    // Store a copy of the url string:
    newNode->url = (char *) malloc(strlen(url)+1);
    strcpy(newNode->url, str);

    newNode->next = NULL;
    
    if (web == NULL) {
        web = newNode;
    } else {
        struct page *curr = web;
        while (curr->next != NULL) {
            // Compare the contents of the two strings
            if (strcmp(newNode->url, curr->url) == 0) {
                printf("URL \"%s\" is already on the web\n", newNode->url);
                // Free both the copied url and the new node itself
                free(newNode->url);
                free(newNode);
                // ...and only then return
                return web;
            } else {
                curr = curr->next;
            }
        }
        curr->next = newNode;
    }
    return web;
    // Remove dead code after this `return`
}

每当您需要删除节点时,请不要忘记在释放节点之前正确释放 url。


推荐阅读