使用 C 的链表分段错误
Segmentation Fault on Linked List Using C
初学C,想学习一下C在链表上的实现。我真的很困惑为什么我不能在 main 函数中访问 myList?因为当我尝试 myList->data
时,这是分段错误。我认为我的 addtohead 函数有一些错误?
下面是我的代码:
#include <stdio.h>
#include <stdlib.h>
typedef struct NODE{
int data;
struct NODE *next;
}node;
node * myList;
node * addToHead(node*, int);
void printList();
int main(){
myList = NULL;
int input;
while (scanf("%i",&input) == 1){
addToHead(myList, input);
printf("%d \n", myList->data);
}
printf("My List:\n");
printList(myList);
return 0;
}
node* addToHead(node* head, int newData){
node *temp = (node *)malloc(sizeof(node));
temp -> data = newData;
temp -> next = NULL;
if(head != NULL){
temp -> next = head;
}
head = temp;
return head;
}
void printList(node* head){
node *temp = head;
while(temp != NULL){
printf("%d ", temp->data);
temp = temp -> next;
}
printf("\n");
}
您 return 来自 addToHead
的新头节点,但您不对其进行任何操作。您需要将此值分配给 myList
才能更新它:
myList = addToHead(myList, input);
此外,您在以下行中拼错了一个变量:
printf("%d \n", myListd->data);
应该是:
printf("%d \n", myList->data);
您的 addToHead 函数应该 return mallocat
ed 内存返回给调用者。
所以你应该先把return值赋给mylist:
int main(){
node *myList = NULL;
int input;
while (scanf("%i",&input) == 1){
myList = addToHead(myList, input);
printf("%d \n", myList->data);
}
printf("My List:\n");
printList(myList);
return 0;
}
进入您编写的 addToHead
函数
head = temp;
但是 head
具有局部作用域,分配的值不会反映到指针 myList
。
为此,您必须使用指向指针的指针。
int main(){
node *myList = NULL;
int input;
while (scanf("%i",&input) == 1)
{
if (addToHead(&myList, input) == true)
{
printf("%d \n", myList->data);
}
else
{
fprintf(stderr, "Error addToHead\n");
}
}
return 0;
}
bool addToHead(node** head, int newData){
node *temp = malloc(sizeof(node));
if (temp != NULL)
{
temp -> data = newData;
temp -> next = NULL;
if(head != NULL)
{
temp -> next = *head;
}
*head = temp;
return true;
}
return false;
}
最后 永远记得检查 malloc
return 值:它可能会失败。
在这个函数定义中
node* addToHead(node* head, int newData){
node *temp = (node *)malloc(sizeof(node));
temp -> data = newData;
temp -> next = NULL;
if(head != NULL){
temp -> next = head;
}
head = temp;
return head;
}
参数node* head
是函数的局部变量。参数的任何更改都不会影响原始参数。函数参数在函数退出后会被销毁
你可以考虑函数定义和调用方式如下
addToHead(myList, input);
//...
node* addToHead(/*node* head, int newData*/){
node *head = myList;
int newData = input;
node *temp = (node *)malloc(sizeof(node));
temp -> data = newData;
temp -> next = NULL;
if(head != NULL){
temp -> next = head;
}
head = temp;
return head;
}
所以函数调用后原变量myList
不会改变。您必须将返回值显式分配给变量
myList = addToHead(myList, input);
该功能也有缺点。如果没有分配新节点,它不会报告错误。
编写函数的更好方法如下所示
int /* _Bool */ addToHead( node **head, int newData )
{
node *temp = ( node * )malloc( sizeof( node ) );
int /* _Bool */ success = temp != NULL;
if ( success )
{
temp -> data = newData;
temp -> next = *head;
*head = temp;
}
return success;
}
在这种情况下,可以通过以下方式在循环中调用该函数
while ( scanf( "%i", &input ) == 1 && addToHead( &myList, input ) )
{
//...
}
初学C,想学习一下C在链表上的实现。我真的很困惑为什么我不能在 main 函数中访问 myList?因为当我尝试 myList->data
时,这是分段错误。我认为我的 addtohead 函数有一些错误?
下面是我的代码:
#include <stdio.h>
#include <stdlib.h>
typedef struct NODE{
int data;
struct NODE *next;
}node;
node * myList;
node * addToHead(node*, int);
void printList();
int main(){
myList = NULL;
int input;
while (scanf("%i",&input) == 1){
addToHead(myList, input);
printf("%d \n", myList->data);
}
printf("My List:\n");
printList(myList);
return 0;
}
node* addToHead(node* head, int newData){
node *temp = (node *)malloc(sizeof(node));
temp -> data = newData;
temp -> next = NULL;
if(head != NULL){
temp -> next = head;
}
head = temp;
return head;
}
void printList(node* head){
node *temp = head;
while(temp != NULL){
printf("%d ", temp->data);
temp = temp -> next;
}
printf("\n");
}
您 return 来自 addToHead
的新头节点,但您不对其进行任何操作。您需要将此值分配给 myList
才能更新它:
myList = addToHead(myList, input);
此外,您在以下行中拼错了一个变量:
printf("%d \n", myListd->data);
应该是:
printf("%d \n", myList->data);
您的 addToHead 函数应该 return mallocat
ed 内存返回给调用者。
所以你应该先把return值赋给mylist:
int main(){
node *myList = NULL;
int input;
while (scanf("%i",&input) == 1){
myList = addToHead(myList, input);
printf("%d \n", myList->data);
}
printf("My List:\n");
printList(myList);
return 0;
}
进入您编写的 addToHead
函数
head = temp;
但是 head
具有局部作用域,分配的值不会反映到指针 myList
。
为此,您必须使用指向指针的指针。
int main(){
node *myList = NULL;
int input;
while (scanf("%i",&input) == 1)
{
if (addToHead(&myList, input) == true)
{
printf("%d \n", myList->data);
}
else
{
fprintf(stderr, "Error addToHead\n");
}
}
return 0;
}
bool addToHead(node** head, int newData){
node *temp = malloc(sizeof(node));
if (temp != NULL)
{
temp -> data = newData;
temp -> next = NULL;
if(head != NULL)
{
temp -> next = *head;
}
*head = temp;
return true;
}
return false;
}
最后 永远记得检查 malloc
return 值:它可能会失败。
在这个函数定义中
node* addToHead(node* head, int newData){
node *temp = (node *)malloc(sizeof(node));
temp -> data = newData;
temp -> next = NULL;
if(head != NULL){
temp -> next = head;
}
head = temp;
return head;
}
参数node* head
是函数的局部变量。参数的任何更改都不会影响原始参数。函数参数在函数退出后会被销毁
你可以考虑函数定义和调用方式如下
addToHead(myList, input);
//...
node* addToHead(/*node* head, int newData*/){
node *head = myList;
int newData = input;
node *temp = (node *)malloc(sizeof(node));
temp -> data = newData;
temp -> next = NULL;
if(head != NULL){
temp -> next = head;
}
head = temp;
return head;
}
所以函数调用后原变量myList
不会改变。您必须将返回值显式分配给变量
myList = addToHead(myList, input);
该功能也有缺点。如果没有分配新节点,它不会报告错误。
编写函数的更好方法如下所示
int /* _Bool */ addToHead( node **head, int newData )
{
node *temp = ( node * )malloc( sizeof( node ) );
int /* _Bool */ success = temp != NULL;
if ( success )
{
temp -> data = newData;
temp -> next = *head;
*head = temp;
}
return success;
}
在这种情况下,可以通过以下方式在循环中调用该函数
while ( scanf( "%i", &input ) == 1 && addToHead( &myList, input ) )
{
//...
}