【问题标题】:Same values with different pointers in a linked list?链表中具有不同指针的相同值?
【发布时间】:2021-10-18 21:40:00
【问题描述】:

为什么这段代码会为链表中的所有节点输出相同的名称?

程序输出

Insert number of users : 
4
Mike
John
Bob
Alice
Name : Alice @ Pointer :0x874ae0 
Name : Alice @ Pointer :0x874b00 
Name : Alice @ Pointer :0x874b20 
Name : Alice @ Pointer :(nil) 

此代码背后的想法是获取x 的用户名数量并创建一个链表,然后循环该链表并打印每个名称以及下一个名称的指针。

typedef struct node
{
    char *name;
    struct node *next;
} node;

int main(void)
{
    int x;
    printf("Insert number of users :\n"); // capture int from user
    scanf("%i", &x);

    char str[LENGTH];

    node *n = malloc(sizeof(node));
    if (n == NULL)
        return 1;

    node *start = n; // pointer to the start of the linked list

    // loop for n times to capture names 
    for (int i = 0; i < x; i++)
    {
        scanf("%s", str); // capture string 
        
        n->name = str;
        // reached end of loop
        if (i == x-1)
            n->next = NULL;
        else 
            n->next = malloc(sizeof(node));
        n = n->next;
    }

    for (node *tmp = start; tmp != NULL; tmp = tmp->next)
    {
        printf("Name : %s @ Pointer :%p\n", tmp->name, tmp->next);
    }
    return 0;
}

一个简单的脚本,用于获取人名并将其插入到链表中。

【问题讨论】:

  • n-&gt;name = str; - 这会将相同的str 分配给所有节点。你需要为每一个分配新的内存
  • n-&gt;name = str; --> n-&gt;name = strdup(str);
  • 永远不要使用scanf("%s",str);永远。如果不限制输入字符串长度并且不检查返回值,则存在缓冲区溢出的风险,这也会在scanf() 失败时导致UB。

标签: c for-loop linked-list dynamic-memory-allocation c-strings


【解决方案1】:

在for循环内的这个语句中

n->name = str;

所有节点的数据成员名设置为数组str声明like的第一个字符的地址

char str[LENGTH];

所以所有节点都将指向同一个数组——即在for循环之后这个数组中最后存储的字符串。

您需要为每个节点动态创建存储在数组中的字符串的副本。类似的东西

#include <string.h>

//...

n->name = malloc( strlen( str ) + 1 );
strcpy( n->name, str );

【讨论】:

  • 我建议strdup。它也在strings.h 中并且非常标准。实际上这完全一样,所以应该注意在使用后应该释放内存(在这两种情况下)。
  • @Cheatah 在支持m 选项的系统上使用char *str=NULL; int r=scanf("%ms",&amp;str); 可能会更好,这样OP 也可以摆脱他的缓冲区溢出问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-14
  • 2020-07-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多