C - 链表 - 插入元素未更新 - 仅添加最后一个输入元素
C - Linked list - Insert element not updated - Only adding last input element
PREFACE:目标是提示用户输入,将每个元素(输入行)添加到link 列表。
我一直在研究 Learn-C.org 中的一些示例代码,其中显示了 linked 列表示例。
我修改了代码,以便它使用 "strings" 而不是整数。
我的insert函数如下:
void push(node_t * head, char *data) {
node_t * current = head;
if(head == NULL) {
printf("First element ever!\n");
}
else if(current->data == NULL) {
current->data = data;
current->next = NULL;
}
else {
while (current->next != NULL) {
current = current->next;
}
current->next = malloc(sizeof(node_t));
current->next->data = data;
current->next->next = NULL;
}
}
现在,在 MAIN 中,我按如下方式启动列表:
node_t * test_list = malloc(sizeof(node_t));
添加元素完成:
push(test_list, "FOO");
push(test_list, "FEE");
push(test_list, "FAA");
打印列表时,使用 print_list(test_list),我得到以下输出:
FOO
FEE
FAA
问题
但是,我随后包含了一个 while 循环,提示用户输入并将其添加到 linked 列表中。
char command[120];
int counter = 0;
while(counter < 3) {
printf("Enter element: ");
fgets((void *)command, sizeof(command), stdin);
push(test_list, command); //Insert
counter++;
}
但是,这不会将每个元素添加到 link 列表中。相反,它将 LAST 元素添加到列表中三次。
例如,提供时:
Enter element: Argentina
Enter element: Mexico
Enter element: Sweden
列表打印为:
FOO
FEE
FAA
Sweden
Sweden
Sweden
EDIT(添加打印功能)
我的print函数如下:
void print_list(node_t * head) {
node_t * current = head;
printf("**** Printing list ****\n");
while (current != NULL) {
printf("%s\n", current->data);
current = current->next;
}
}
我错过了什么,或者:我该如何解决这个问题?非常感谢任何帮助。
你有一个容量为 120 的数组 command
。你用它来读入值。这个可以。
然后你发送一个指向这个数组的指针来存储。已存储,一切正常。
下次读取输入时,将其读取到同一个数组,并为其提供了一个要存储的指针。因此,您正在更改该指针指向的内存内容。这不行。
您需要为每个字符串分配单独的内存区域并处理它们的释放。 strdup
是获取包含用户输入内容的新内存块的最简单方法。
但是请记住,当您不再需要内存时,您确实必须释放内存。在这种情况下,您可能永远不会删除任何字符串,但当您这样做时,您不能只删除元素,还必须释放字符串使用的内存。
current->data = data;
这里你只复制指针地址而不是数据,在那个地址('command' 的地址)上最后一个数据('Sweden')将可用。
你应该使用 strcpy(current->data,data)
来复制数据。
使用strdup
到return堆上分配的字符串副本。
The strdup() function returns a pointer to a new string which is a duplicate of the string s. Memory for the new string is obtained with malloc(3), and can be freed with free(3).
node_t *test_list = malloc(sizeof(node_t));
test_list->next = NULL;
test_list->data = NULL;
while(counter < 3) {
printf("Enter element: ");
fgets((void *)command, sizeof(command), stdin);
push(test_list, strdup(command)); //Insert
counter++;
}
PREFACE:目标是提示用户输入,将每个元素(输入行)添加到link 列表。
我一直在研究 Learn-C.org 中的一些示例代码,其中显示了 linked 列表示例。 我修改了代码,以便它使用 "strings" 而不是整数。
我的insert函数如下:
void push(node_t * head, char *data) {
node_t * current = head;
if(head == NULL) {
printf("First element ever!\n");
}
else if(current->data == NULL) {
current->data = data;
current->next = NULL;
}
else {
while (current->next != NULL) {
current = current->next;
}
current->next = malloc(sizeof(node_t));
current->next->data = data;
current->next->next = NULL;
}
}
现在,在 MAIN 中,我按如下方式启动列表:
node_t * test_list = malloc(sizeof(node_t));
添加元素完成:
push(test_list, "FOO");
push(test_list, "FEE");
push(test_list, "FAA");
打印列表时,使用 print_list(test_list),我得到以下输出:
FOO
FEE
FAA
问题
但是,我随后包含了一个 while 循环,提示用户输入并将其添加到 linked 列表中。
char command[120];
int counter = 0;
while(counter < 3) {
printf("Enter element: ");
fgets((void *)command, sizeof(command), stdin);
push(test_list, command); //Insert
counter++;
}
但是,这不会将每个元素添加到 link 列表中。相反,它将 LAST 元素添加到列表中三次。
例如,提供时:
Enter element: Argentina
Enter element: Mexico
Enter element: Sweden
列表打印为:
FOO
FEE
FAA
Sweden
Sweden
Sweden
EDIT(添加打印功能)
我的print函数如下:
void print_list(node_t * head) {
node_t * current = head;
printf("**** Printing list ****\n");
while (current != NULL) {
printf("%s\n", current->data);
current = current->next;
}
}
我错过了什么,或者:我该如何解决这个问题?非常感谢任何帮助。
你有一个容量为 120 的数组 command
。你用它来读入值。这个可以。
然后你发送一个指向这个数组的指针来存储。已存储,一切正常。
下次读取输入时,将其读取到同一个数组,并为其提供了一个要存储的指针。因此,您正在更改该指针指向的内存内容。这不行。
您需要为每个字符串分配单独的内存区域并处理它们的释放。 strdup
是获取包含用户输入内容的新内存块的最简单方法。
但是请记住,当您不再需要内存时,您确实必须释放内存。在这种情况下,您可能永远不会删除任何字符串,但当您这样做时,您不能只删除元素,还必须释放字符串使用的内存。
current->data = data;
这里你只复制指针地址而不是数据,在那个地址('command' 的地址)上最后一个数据('Sweden')将可用。
你应该使用 strcpy(current->data,data)
来复制数据。
使用strdup
到return堆上分配的字符串副本。
The strdup() function returns a pointer to a new string which is a duplicate of the string s. Memory for the new string is obtained with malloc(3), and can be freed with free(3).
node_t *test_list = malloc(sizeof(node_t));
test_list->next = NULL;
test_list->data = NULL;
while(counter < 3) {
printf("Enter element: ");
fgets((void *)command, sizeof(command), stdin);
push(test_list, strdup(command)); //Insert
counter++;
}