链接的字符串列表对于每个节点具有相同的字符串

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了链接的字符串列表对于每个节点具有相同的字符串相关的知识,希望对你有一定的参考价值。

我正在尝试创建一个链表,每个节点都存储一个字符串,但我遇到的问题是每个节点最终在每个节点中存储相同的字符串。在main()的末尾,我打印出存储在每个节点中的单词,它总是只重复为整个列表输入的最后一个字符串。

我不知道发生了什么,因为如果我把它变成一串字符就可以很好地工作,每个字符都存储在正确的节点中。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

struct wordnode {
    char *word;
    struct wordnode *next;
};

struct wordnode *link = NULL;

void addword(char *aword);

int main(void) {


    char *aword;
    int i;

    for(i = 0; i < 10; i++) {
        scanf(" %s", aword);
        addword(aword);
    }
    printf("\n");
    for(; link != NULL; link = link->next) {
        printf("|%s ", link->word);
    }

    printf("|\n");
    return 0;
}

void addword(char *aword) {
    struct wordnode *cur, *prev, *new_node;

    new_node = malloc(sizeof(struct wordnode));

    new_node->word = aword;

    for(cur = link, prev = NULL; cur != NULL; prev = cur, cur = cur->next) {
        ;
    }

    new_node->next = cur;

    if(prev == NULL) {
        link = new_node;
    } else {
        prev->next = new_node;
    }
}
答案

代码中存在许多问题。其中一些已被提及。代码将是这样的。代码末尾的解释。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define STR2(x) #x
#define STR(X) STR2(X)
#define MAXWORD 10
#define MAXWORDLEN 20

struct wordnode {
    char *word;
    struct wordnode *next;
};


struct wordnode* addword(char *aword, struct wordnode *link);
void printList(struct wordnode*link);
void freeList(struct wordnode *link);

int main(void) {
    char aword[MAXWORDLEN+1];

    struct wordnode *link = NULL;
    for(size_t i = 0; i < MAXWORD; i++) {
        if( scanf("%" STR(MAXWORDLEN) "s", aword[i]) == 1 ){
           link = addword(aword, link);
        }
        else{
            fprintf(stderr, "%s\n","Error in input" );
            exit(1);
        }
    }

    printList(link);  

    freeList(link);
    return 0;
}
void printList(struct wordnode*link){
    while(link){
        printf("%s \n", link->word);
        link  = link->next;
    }
}
void freeList(struct wordnode *link){
    struct wordnode *temp;
    while(link){
        temp = link;
        link = link->next;
        free(temp);
    }
}

struct wordnode* addword(char *aword, struct wordnode *link) {

    struct wordnode *new_node = malloc(sizeof(struct wordnode));

    if( new_node == NULL){
        fprintf(stderr, "%s\n", "Error in malloc");
        exit(1);
    }
    new_node->word = strdup( aword );
    if( new_node->word == NULL){
        fprintf(stderr, "%s\n", "Error in strdup" );
        exit(1);
    }
    new_node->next = NULL;

    if( link == NULL){
        return new_node;
    }
    struct wordnode *cur = link;
    while( cur->next != NULL ){
        cur = cur -> next;
    }
    cur->next = new_node;
    return link;
}

您想存储一些字符串(空终止的char数组),然后您想在列表中添加它们。同样从您的示例实现中,您尝试将其添加到尾部的列表中。

总结一下 -

  • scanf需要一个指向某个存储器的指针,它可以存储输入的数据。但你的未初始化。
  • 其次,你复制字符串的方式,它只是一个浅的副本(你让它指向一些已经存在的内存)。你需要使用strdupmalloc - memcpymalloc-strcpy复制它。
  • 如果POSIX strdup()不可用,您可以使用Jonathan Leffler提到的内容。
  • 在这里你可以看到我们已经使用freeList()函数释放了已分配的内存。当您完成使用已分配的内存时 - 释放内存。
  • 不要强制转换malloc的返回值。
  • 还要检查malloc是否成功检查它的返回值。
  • 您已将列表头用作全局变量。这里不需要它。
另一答案

char * aword未初始化和定位。它应该是:

char aword[100];

(100只是一个数字,大小的数组。你可以用你想要的任何数字替换它)

另一答案

您尚未为字符串分配内存。因此,aword将包含垃圾值并将其传递给scanf是一种未定义的行为。让我们说aword0x7fffe4e0cdf0和你的scanf将字符串存储在地址0x7fffe4e0cdf0并将此地址传递给addword函数,你的结构成员word也更新了相同的值。下一个scanf还将新值存储在aword指向的相同内存中并传递给该函数。因此,所有链表中的word指向相同的内存位置。理想的解决方案是为每个被扫描的字符串分配内存,并将其传递给“addword”函数。

以上是关于链接的字符串列表对于每个节点具有相同的字符串的主要内容,如果未能解决你的问题,请参考以下文章

Python:如何将具有相同变量类型的多个列表合并到一个列表列表中?

[HAOI2016]找相同字符

在 Python 中为具有 ANSI 颜色代码的字符串获取正确的字符串长度

pydot:是不是可以绘制两个具有相同字符串的不同节点?

Pyspark 将列表列转换为嵌套结构列

如何使 WPF 列表框中的列对于所有项目具有相同的宽度?