通过函数添加时,新节点未正确添加到链表末尾
New node doesnt get properly added to end of linked list when adding through function
我正在尝试通过添加节点的函数将新节点添加到链表。但是当我打印列表时,似乎所有节点中的数据都被最近添加的数据所取代。
typedef struct things {
char *string;
struct things *next;
} something;
void addnode(something **head, char *str);
void printlist(something **head);
int main()
{
int i;
char word[50];
something *head = NULL;
puts("How many strings?");
scanf("%d", &i);
while(i > 0)
{
scanf("%49s", word);
addnode(&head, word);
i--;
}
printlist(&head);
return 0;
}
void addnode(something **head, char *str)
{
something *last = *head;
something *newnode;
newnode = malloc(sizeof(something));
newnode->string = malloc(50*sizeof(char));
newnode->string = str;
newnode->next = NULL;
if ((*head)==NULL)
{
(*head) = newnode;
return;
}
else
{
while(last->next != NULL)
{
last=last->next;
}
last->next = newnode;
return;
}
}
void printlist(something **head) //print contents of list, to check if list was created
{
puts("print");
something *current = *head;
while(current != NULL)
{
printf("%s", current->string);
current=current->next;
}
}
这是我想到的。当我输入 say 5 words one
two
three
four
five
时,我得到输出 five five five five five
。这是我尝试打印的方式的问题吗?还是与我传递指针和链接节点的方式有关?
函数 addnode() 而不是
newnode->string = malloc(50*sizeof(char));
newnode->string = str;
尝试
newnode->string = strdup(str);
应该可以。 :)
分配指针不会复制它们的内容。只是让它们指向相同的内存地址。
在您的代码中,您正在为新节点的 str
分配内存,并使其指向缓冲区的地址(word
对于您的情况)。通过这样做,最终所有节点的 str
将指向缓冲区最后一个值的地址的内容(对于你的情况是五个)。
newnode->string = malloc(50*sizeof(char));
newnode->string = str;
这里的另一个问题是您没有根据缓冲区的内容动态分配内存。
要准确分配所需的内存量,试试这个:
替换:
newnode->string = malloc(50*sizeof(char));
与:
newnode->string = malloc((strlen(str)+1)*sizeof(char));
使用 strlen
可以得到字符数,+1
用于分配 space 用于终止字符 '[=20=]'
。
因此,要解决最初的问题,您需要将缓冲区的内容复制到新分配的内存中:
替换:
newnode->string = str;
和
strcpy(newnode->string,str);
改变插入功能,如
void addnode(something **head, char *str)
{
something *last = *head;
something *newnode;
newnode = malloc(sizeof(something));
newnode->string = malloc(50*sizeof(char));
strcpy(newnode->string, str);
newnode->next = NULL;
if ((*head)==NULL)
{
(*head) = newnode;
return;
}
else
{
while(last->next != NULL)
{
last=last->next;
}
last->next = newnode;
return;
}
}
我正在尝试通过添加节点的函数将新节点添加到链表。但是当我打印列表时,似乎所有节点中的数据都被最近添加的数据所取代。
typedef struct things {
char *string;
struct things *next;
} something;
void addnode(something **head, char *str);
void printlist(something **head);
int main()
{
int i;
char word[50];
something *head = NULL;
puts("How many strings?");
scanf("%d", &i);
while(i > 0)
{
scanf("%49s", word);
addnode(&head, word);
i--;
}
printlist(&head);
return 0;
}
void addnode(something **head, char *str)
{
something *last = *head;
something *newnode;
newnode = malloc(sizeof(something));
newnode->string = malloc(50*sizeof(char));
newnode->string = str;
newnode->next = NULL;
if ((*head)==NULL)
{
(*head) = newnode;
return;
}
else
{
while(last->next != NULL)
{
last=last->next;
}
last->next = newnode;
return;
}
}
void printlist(something **head) //print contents of list, to check if list was created
{
puts("print");
something *current = *head;
while(current != NULL)
{
printf("%s", current->string);
current=current->next;
}
}
这是我想到的。当我输入 say 5 words one
two
three
four
five
时,我得到输出 five five five five five
。这是我尝试打印的方式的问题吗?还是与我传递指针和链接节点的方式有关?
函数 addnode() 而不是
newnode->string = malloc(50*sizeof(char));
newnode->string = str;
尝试
newnode->string = strdup(str);
应该可以。 :)
分配指针不会复制它们的内容。只是让它们指向相同的内存地址。
在您的代码中,您正在为新节点的 str
分配内存,并使其指向缓冲区的地址(word
对于您的情况)。通过这样做,最终所有节点的 str
将指向缓冲区最后一个值的地址的内容(对于你的情况是五个)。
newnode->string = malloc(50*sizeof(char));
newnode->string = str;
这里的另一个问题是您没有根据缓冲区的内容动态分配内存。
要准确分配所需的内存量,试试这个:
替换:
newnode->string = malloc(50*sizeof(char));
与:
newnode->string = malloc((strlen(str)+1)*sizeof(char));
使用 strlen
可以得到字符数,+1
用于分配 space 用于终止字符 '[=20=]'
。
因此,要解决最初的问题,您需要将缓冲区的内容复制到新分配的内存中:
替换:
newnode->string = str;
和
strcpy(newnode->string,str);
改变插入功能,如
void addnode(something **head, char *str)
{
something *last = *head;
something *newnode;
newnode = malloc(sizeof(something));
newnode->string = malloc(50*sizeof(char));
strcpy(newnode->string, str);
newnode->next = NULL;
if ((*head)==NULL)
{
(*head) = newnode;
return;
}
else
{
while(last->next != NULL)
{
last=last->next;
}
last->next = newnode;
return;
}
}