【问题标题】:Segmentation fault while creating a linked list创建链表时出现分段错误
【发布时间】:2018-02-17 21:30:58
【问题描述】:

我正在编写一个小程序,它将数据和键存储在链表结构中,并根据用户的键检索数据。该程序还检查它是否是唯一键,如果是唯一键,它会通过在列表的前面创建一个节点来存储数据。但是下面的代码总是抛出分段错误。

 #include<stdlib.h>

/* Node having data, unique key, and next */.  
struct node
{
    int data;
    int key;
    struct node *next;
}*list='\0',*p;

/* Create a node at the front */
void storeData(int data_x,int key_x)
{
    int check_key;
    position *nn;  //nn specifies newnode
    nn=(position)malloc(sizeof(struct node));

/* Segmentation Fault occurs here */
    if(list->next==NULL)
    {
        nn->next=list->next;
        nn->data = data_x;
        nn->key = key_x;
        list->next = nn;
    }
    else
    {
      check_key=checkUniqueKey(key_x);
      if(check_key != FALSE)
      {
         printf("The entered key is not unique");
      }
      else
      {
          nn->data = data_x;
          nn->key = key_x;
          nn->next=list->next;
          list->next=nn;
      }

   }
}

/* Retreive data based on a key */

int retreiveData(int key_find)
{
   int ret_data = NULL;
   p=list->next;
   while(p->next != NULL)   
   {
        if(p->key == key_find)
        {
            ret_data = p->data;
            break;
        }
     p=p->next;
   }  
   return(ret_data);
}
/*  Checks whether user key is unique */
int checkUniqueKey(int key_x)
{
    int key_check = FALSE;
    p=list->next;
    while(p->next != NULL)
    {
        if(p->key == key_x)
        {
          key_check = TRUE;
          break;    
        }
      p=p->next;
    }
    return(key_check);
}

动态分配后storeData函数出现分段错误。

【问题讨论】:

  • if(list-&gt;next==NULL) { nn-&gt;next=list-&gt;next; 您在此处取消引用 NULL 指针。另外:*list='\0' 不是指针的正确初始化程序。
  • 像这样使用全局变量是非常糟糕的;不要将'\0' 分配给指针,不要将NULL 分配给int;代码不完整,但我在任何地方都没有找到你的malloc listlist-&gt;next 可能因为这个原因而被引用为 NULL
  • @Coder:你为什么回滚我的编辑?

标签: c linked-list singly-linked-list


【解决方案1】:

你的代码有一些问题:

  • 您的列表处理存在缺陷:您总是取消引用全局指针list,甚至在创建任何列表项之前。您应该通过比较 listNULL 来测试列表是否为空。

  • 类型position 未定义。避免将指针隐藏在 typedef 后面,这是造成混淆的主要原因,这解释了您对列表指针的处理不当。

  • 避免使用名称p 定义全局变量,这无论如何都不需要。在使用它的函数中将p 定义为局部变量。

  • NULL 是空指针,0 是零整数值,\0 是 C 字符串末尾的空字节。所有 3 都评估为 0 但并不总是可以互换的。 为获得更好的可移植性和可读性,请针对每种情况使用适当的。

这是一个改进的版本:

#include <stdio.h>
#include <stdlib.h>

/* Node having data, unique key, and next */.  
struct node {
    int data;
    int key;
    struct node *next;
} *list;

/* Create a node at the front */
void storeData(int data_x, int key_x) {
    if (checkUniqueKey(key_x)) {
        printf("The entered key is not unique\n");
    } else {
        /* add a new node to the list */
        struct node *nn = malloc(sizeof(struct node));
        if (nn == NULL) {
            printf("Cannot allocate memory for node\n");
            return;
        }
        nn->data = data_x;
        nn->key = key_x;
        nn->next = list;
        list = nn;
    }
}

/* Retrieve data based on a key */
int retrieveData(int key_find) {
    struct node *p;
    int ret_data = 0;

    for (p = list; p != NULL; p = p->next) {
        if (p->key == key_find) {
            ret_data = p->data;
            break;
        }
    }
    return ret_data;
}

/* Checks whether user key is unique */
int checkUniqueKey(int key_x) {
    struct node *p;
    int key_check = FALSE;

    for (p = list; p != NULL; p = p->next) {
        if (p->key == key_x) {
            key_check = TRUE;
            break;  
        }
    }
    return key_check;
}

【讨论】:

    【解决方案2】:

    您尝试将地址投射到职位结构而不是职位* nn=(position)malloc(sizeof(struct node)); 使用 gcc 标志 -Wextra 和 -Wall 编译代码以防止出现此类问题。 此外,我不知道这是一个错误,但 malloc 结构节点的大小,而您的 nn 变量是位置指针。

    【讨论】:

    • typedef 结构节点* 位置;我已经在我的代码中包含了这个语句
    • 你的 nn 变量是一个postion *,所以它是一个struct node **,你确定这是你想做的吗?
    【解决方案3】:

    当您初始化 list 指针时,您将其设置为 NULL(作为 '\0'),当程序访问地址 0x00 时,它会超出其边界并且操作系统会终止该进程。

    为避免段错误,您可以拥有非指针类型的“列表”,从而在堆栈上分配,当您想将列表作为指针访问时,您可以执行&amp;list。另一种解决方案是在堆栈“root_node”上有变量并将list指针初始化为list = &amp;root_node

    【讨论】:

      猜你喜欢
      • 2014-05-19
      • 2014-01-25
      • 2021-12-10
      • 2016-06-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多