我正在尝试创建一个包含 10 个节点的列表,并分配值 1 到 10 并打印它们。我用以下代码尝试了它,但我最终遇到了分段错误。
我对 C 语言中的链表很陌生。
#include<stdio.h>
typedef struct Node
{
int data;
struct Node *next;
}Node_Struct;
int main(void)
{
int i =0;
Node_Struct* Node = NULL;
Node = (Node_Struct*)malloc(sizeof(Node_Struct));
for (i = 1; i<=10; i++){
Node->data = i;
Node = Node->next;
}
for (i = 1; i<=10; i++){
printf("n Node->data:%d",Node->data);
Node = Node->next;
}
return 0;
}
正如人们在评论中指出的那样,您只将内存分配给头节点。您还需要为尝试添加 int for 循环的每个节点分配内存。此外,您在每次迭代时都会向前移动Node
指针,因此插入后将无法遍历列表。跟踪列表的正面和尾部。执行以下操作:
维护链表的头部和尾部:
Node_Struct* headNode = NULL, *tailNode = NULL;
// head node
headNode = tailNode = (Node_Struct*)malloc(sizeof(Node_Struct));
在循环中的每次迭代时分配内存。是否要在头节点中保留某些内容是你的愿望。因此,像这样更改 for 循环中的代码:
for (i = 1; i<=10; i++) {
Node_Struct* newNode = (Node_Struct *)malloc(sizeof(Node_Struct));
newNode->data = i;
newNode->next = NULL;
tailNode->next = newNode;
tailNode = newNode;
}
在此之后,您可以通过在其他变量中复制头值来迭代列表:
Node_Struct *tmpNode = headNode;
for (i = 1; i<=10; i++){
printf("n Node->data:%d",tmpNode->data);
tmpNode = tmpNode->next;
}
您不会为每个添加的节点分配内存。
如果要使用您的循环,那么进行这些小的更改就足够了
Node_Struct* Node = NULL;
Node_Struct **current = &Node;
for (i = 1; i <= 10; i++ ) {
*current = malloc(sizeof(Node_Struct));
(*current)->data = i;
(*current)->next = NULL;
current = &(*current)->next;
}
current = &Node;
for (i = 1; i <= 10; i++) {
printf("n Node->data:%d", ( *current )->data);
current = &( *current )->next;
}
考虑到您应该在退出程序之前释放节点的所有分配内存。
您只为单个节点分配了空间,但您正在尝试通过执行以下操作来遍历链接节点的列表:
for (i = 1; i<=10; i++){
Node->data = i;
Node = Node->next;
}
当你这样做时 - Node = Node->next;
,Node
可能指向任何地方。你可能指向你不应该触摸的记忆。
要记住的一件事是永远不要放开列表顶部的把柄。通过维护副本来保留指向列表头部的指针。
Node = malloc(sizeof(Node_Struct));
Node_Struct *head = Node;
使用 malloc()
为每个节点分配空间。首先建立节点列表。一种方法是这样的:
for (i = 1; i<=10; i++){
Node->next = malloc(sizeof (Node_Struct));
Node = Node->next;
}
Node->next = NULL // The last node should point to NULL
之后,您可以在另一个循环中设置节点的所有data
字段,或者在执行malloc()
时将它们设置在同一循环中。由于您已经拥有列表head
的句柄,因此您知道从哪里开始。这样:
Node = head;
i = 0;
while (Node) {
Node->data = i++;
Node = Node->next;
}
我向您展示您的错误在哪里,下面我为您重写了代码以解决您的问题。查看我的代码并与您的代码进行比较。希望这能帮助你学习数据结构。
让我们看看你的错误
#include<stdio.h>
typedef struct Node
{
int data;
struct Node *next;
}Node_Struct;
int main(void)
{
int i =0;
Node_Struct* Node = NULL;
Node = (Node_Struct*)malloc(sizeof(Node_Struct));
for (i = 1; i<=10; i++){
Node->data = i;/* till here everything fine */
Node = Node->next; /* now you are pointing to nowhere */
/* in the next iteration of for loop Node->data = i will crash the application */
/* you could have done it like below
Node->next = (Node_Struct*)malloc(sizeof(Node_Struct));
Node = Node->next;
Node->data = i;
Node->next = NULL
but here you lost the address of first node so all gone*/
}
for (i = 1; i<=10; i++){
printf("n Node->data:%d",Node->data);
Node = Node->next;
}
return 0;
}
现在在下面查看我的代码
int main(void)
{
int i =0;
Node_Struct *Node = NULL;
Node_Struct *p = NULL;
for (i = 1; i<=10; i++){
if ( Node == NULL )
{
Node = (Node_Struct*)malloc(sizeof(Node_Struct));
Node->data = i;
Node->next = NULL;
p = Node; /* p is pointing to the first Node of the list */
}
else
{
p->next = (Node_Struct*)malloc(sizeof(Node_Struct));
p = p->next;
p->data = i;
p->next = NULL;
}
}
p = Node; /* now p is pointing to first node of the link list */
/* if you see above we always assign NULL to 'next' pointer so that the last node of the list pointing to NULL */
/* Therefore in the below while loop we are searching the list untill we reach the last node */
while( p != NULL )
{
printf("n p->data:%d",p->data);
p = p->next;
}
return 0;
}