打印链表总是打印最后一个节点

Printing linked list always prints last node

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

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

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

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

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

其他一些问题:

  • 您不应该通过比较字符指针来检测重复节点,而应该使用 strcmp.
  • 比较字符串内容
  • 您的 return 语句后有无效代码。在第一种情况下,free 调用应该发生在 之前 return 语句。然而,最后的 free 在此函数中没有任何意义。那应该稍后发生,此时你想删除一个节点或整棵树,而不是在这个函数中。
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。