【问题标题】:Segmentation fault (core dumped) while running the program运行程序时出现分段错误(核心转储)
【发布时间】:2013-05-04 23:02:42
【问题描述】:
#include<stdio.h>
#include<string.h>
#include<malloc.h>
//#include<conio.h>
struct list
{
char *value;
struct list *link;
};
struct list *arr[12];int val;
int hf(char *item)
{
int sum,i=0;
while(item[i]!='\0')
{
    sum+=item[i];
    i++;
}
return sum%12;
}
void insert(struct list ** arr,char *item,int val)
{
struct list *temp,*r;
r=*arr;
     temp=(struct list *)malloc(sizeof(struct list));
 strcpy((temp->value),item);
  if(strcmp((r->value),NULL))
  {
      strcpy((r->value),(temp->value));
      (r->link)=NULL;
  }
  else
  {
      while(r->link!=NULL)
        r=r->link;
      r->link=temp;
      r=r->link;
       strcpy((r->value),(temp->value));
      r->link=NULL;

  }
 *arr=r;

}
void main()
{
  struct list *li[12];int i=0;
  for(i=0;i<12;i++)
  {
      li[i]=NULL;
  }
  char *item;int ret;
  strcpy(item,"Steve");
  ret=hf(item);
  insert(&li[ret],item,ret);
  strcpy(item,"raj");
  ret=hf(item);
  insert(&li[ret],item,ret);
  strcpy(item,"Notes");
  ret=hf(item);
  insert(&li[ret],item,ret);
}

上面的程序是实现链表数组,我试图插入字符串 作为价值。当我尝试运行程序时,没有错误,但它告诉分段错误(核心转储) 所以请解释原因

【问题讨论】:

  • 请注意,您的 hf() 函数可以返回负值。对哈希值、大小和索引使用无符号类型是一个好习惯。另外:2) main() 应返回 int,3) 不要强制转换 malloc() 的返回值,4) 不要使用太多不需要的 () 括号。 5)使用一些空格,尤其是在运算符周围。顺便说一句,您的 insert(&amp;li[ret],item,ret); 应该检查 (ret &gt;= 0 &amp;&amp; ret &lt; 12)

标签: c data-structures segmentation-fault malloc singly-linked-list


【解决方案1】:

代码

char *item;int ret;
strcpy(item,"Steve");

尝试将字符串文字"Steve" 复制到未初始化的指针。您需要为item 分配内存。最简单的方法是硬编码适当大小的堆栈缓冲区

char item[50];

insert 内部也有类似的问题。你可以用同样的方法解决这个问题

struct list
{
    char value[50];
    struct list *link;
};

或者你可以在insert中动态分配正确大小的缓冲区

temp->value = malloc(strlen(item) + 1);
if (temp->value == NULL) {
    /* handle oom error */
}
strcpy(temp->value, item);

在后一种方法中,请确保在释放该列表节点时使用free(node-&gt;value)。另请注意,您的程序当前缺少释放所有动态分配的内存,这意味着您泄漏了使用 malloc 分配的所有内存。

您的代码中还有一个错误 - insert 假定 arr 是指向有效 list* 的指针,但它始终是 NULL。您需要在此处更新maininsert 中的假设。

【讨论】:

  • 即使我尝试了 item[50] 仍然显示相同的错误。插入函数有没有漏洞
  • 您的第一条评论分配了一个 1 字符的缓冲区,然后您尝试将 6 字符的字符串写入该缓冲区。您的第二条评论应该修复第一个错误,但会在以后的错误中失败。有关详细信息,请参阅我的更新答案。
  • 我试过 struct list { char value[50];结构列表*链接; };同样的错误
  • 我的回答中也提到了最后一个错误。尝试阅读调试器的使用。这会告诉你这些问题的确切位置。
  • insert 中发生的任何更改都会反映到 li[ret] 对吗?那么它将如何始终为空。
【解决方案2】:

改变以下内容

在 insert() 函数中更改 if 循环

if(r==NULL){
    r = temp;
}

改变结构。根据需要更改结构的大小

struct list
{
char value[25];
struct list *link;
};

将变量项改为

字符项[25];

编辑: 无需对 malloc 的输出进行类型转换

【讨论】:

  • 没有为结构列表 *r 分配任何内存。所以我们必须引用新节点。否则复制时会显示分段错误
猜你喜欢
  • 2014-09-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-13
  • 2017-02-18
相关资源
最近更新 更多