C语言中的链表和字符串问题

4

我正在尝试在C语言中创建一个带有头节点和尾节点的链表。每个节点需要保存一个整数和一个字符串。我的问题是,当我创建一个新节点,为其分配正确的值并将其添加到列表末尾时,所有先前的节点都会获得我为最新节点分配的字符串。整数值保持正确,但好像它们的字符指针被重新分配了。我猜测我在指针方面做错了什么,并查看了许多在线示例,但找不出错误所在。我包含了我的节点结构和添加函数。感谢您的所有帮助!

// Linked list (queue) for requests
typedef struct request {
    struct request *next;
    int request_id;
    char *command;
} request_t;

// Global variables
request_t *head = NULL;
request_t *tail = NULL;

void add(int r_id, char *c) {
    request_t *node = NULL;
    node = (request_t *)malloc(sizeof(request_t));

    node->request_id = r_id;
    node->command = c;
    node->next = NULL;

    if(head == NULL) {
        head = node;
        tail = node;
    } else {
        tail->next = node;
        tail = node;

    }   
}

你的错误不在于指针,而在于指针所指向的内容。你需要学习动态内存分配;我建议你拿起一本好书和一杯咖啡。 - Kerrek SB
你的 add 函数看起来没问题,所以我猜问题在于你正在使用相同的第二个参数调用 add。如果不是这种情况,请提供更多信息:你是如何调用你的 add 函数的? - sirgeorge
这些孩子们为什么连简单的、非不透明数据类型都要使用typedef呢? - tbert
3个回答

4

您需要创建字符串的副本。

例如,在 add 函数中,您需要这行代码:

node->command = strdup(c);

此外,当您释放节点时,您还需要释放此字符串以防止内存泄漏。

1
node->command = c;

应该是这样的:

// Allocate enough memory for a copy of the string pointed to by c
node->command = malloc(strlen(c) + 1);

// Copy the string pointed to by c, to the newly allocated memory
strcpy(node->command, c);

或者,由于您必须在 c 上调用 strlen,因此可以使用更高效的方法:

size_t num_bytes = strlen(c) + 1;

// Allocate enough memory for a copy of the string pointed to by c
node->command = malloc(num_bytes);

// Copy num_bytes bytes from the memory pointed to by c, to the newly allocated memory
memcpy(node->command, c, num_bytes);

这样你就可以复制字符串了。你的删除函数应该被修改为释放已分配的内存:

free(node->command);

你的代码有什么问题?

如果你没有复制字符串,而是只复制了指针,那么如果你调用 add(10, somestr);,那么 somestr 就是一个 char *(一个指针)。如果你修改该内存位置上的字符串,由于实际上只有一个字符串有两个指向它的指针(command 和 somestr),因此在你的链表中也会被修改。


0
我从来不知道可以使用 '=' 运算符将一个字符串赋值给另一个字符串 :P 这可能对结构体变量有效,但对字符串无效。在动态分配大小给 node->command 后尝试使用 strcpy(node->command, c)。这应该可以解决问题! :)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接