【问题标题】:C Segmentation Fault - linked lists [closed]C分段错误 - 链表[关闭]
【发布时间】:2013-11-28 20:09:41
【问题描述】:

几周前我刚刚开始使用 C 进行编程,但我的程序出现了分段错误。

我相信是因为这些台词:

for (int i =0; i < HOW_MANY; i++) 
         {
        people = people -> next;
        if (people -> next == NULL) return people;
     } //for
      }//else

这是我的 C 程序,带有基于我的 psedocode 的 cmets

struct person *insert_end (struct person *people, char *name, int age) {
//create a new space for the new person
  struct person *pointer = malloc(sizeof(struct person));
   // check it succeeded
    if(pointer == NULL)
    { 
     printf("The program could not allocate memory ");
      exit(-1);
    }
     // set the data for the new person
      strcpy(pointer -> name, name);
      pointer -> age = age;
      pointer -> next = people;
     // if the current list is empty
      if (people == NULL)
      {
        // set the new person's "next" link to point to the current list"
    pointer -> next = people;
    // return a pointer to the new person
    return pointer;
      }
      else  
      {
     // we need a loop to find the last item in the list 
    // (the one which as a "next" link of NULL)
         for (int i =0; i < HOW_MANY; i++) 
         {
       // set the "next link of this item to point
           // to the new person, so that the person
           // becomes the last item in the list
           // (the next person should have a "next" link of NULL)
        people = people -> next;
        if (people -> next == NULL)
        return people;
     } //for
      }//else
       // return the start of the list
       return pointer;    
}

另外,如果您需要我的完整 C 代码,请告诉我,因为这只是一种方法

谢谢,

莎拉 :)

【问题讨论】:

  • 可能更适合CodeReview
  • 你说 if (person == 0)(*lastItem.next) = people; 但没有变量叫做 person ad lastitem。而且还有其他类似的问题,所以很难弄清楚你在哪一部分遇到了麻烦。
  • 如果你试图在列表的开头或结尾插入新的人,你的伪代码并不清楚这一事实,这很复杂。首先,您将新人放在列表的开头,然后将其放在列表的开头,然后执行循环以查找列表的结尾 - 更不用说当列表为空时您仍然指向它。

标签: c list linked-list segmentation-fault


【解决方案1】:

这完全是 Code Review 的问题,但既然你确实问了一个关于如何实现算法的问题,至少我认为它适合 Stack Overflow。

对于初学者来说,这只是一个语法问题,但我认为你应该替换它:

(*pointer).age = age;

有了这个

pointer -&gt; age = age;

在我看来,这种表示法更简洁,并被合并到 C 中,用于从结构指针访问元素。除此之外,您到目前为止的代码缺少一些右括号。这是您的代码版本,具有正确的语法和其他重要内容(例如@H2CO3 提到的内容):

struct person *insert_end (struct person *people, char *name, int age) {

//create a new space for the new person
struct person *pointer = malloc(sizeof(struct person));

// check it succeeded
if(pointer == NULL)
{ 
    printf("The program could not allocate memory ");
    exit(-1);
}

// set the data for the new person
strcpy(pointer -> name, name);
pointer -> age = age;
pointer -> next = people;

// if the current list is empty
if (person == 0)
{
    // set the new person's "next" link to point to the current list"
    pointer -> next = people;

    // return a pointer to the new person
    return pointer;
}

else
{
    // we need a loop to find the last item in the list 
    // (the one which as a "next" link of NULL)
    for (int i =0; i < HOW_MANY; i++) 
    {
        // set the "next link of this item to point
        // to the new person, so that the person
        // becomes the last item in the list
        // (the next person should have a "next" link of NULL)
        lastItem -> next = people;
    }

    // return the start of the list
    return pointer;    
}

}

最后,由于我没有你的整个代码的完整副本,我也不想要它,我可以为你提供关于如何实现你不确定的伪代码部分的建议。

使用循环查找列表中的最后一项(即具有 NULL的“下一个”链接)

查找链表中的最后一项很简单。我在下面精心制作的以下函数显示了如何在某个索引处获取链表中的特定节点:

NODE* getNode(NODE* start, int index)
{
    int i;
    for(i = 0; i < index; i++)
    {
        start = start -> next;
    }
    return start;
}

可以修改此代码,使其返回最后一个节点。

NODE* getLastNode(NODE* start)
{
    for(;;)
    {
        start = start -> next;
        if(start -> next == NULL)
            return start;
    }
}

上面的代码遍历列表中的每个节点,直到找到一个连接节点为NULL 的节点。然后它返回最后一个节点。

现在您可以调用上面的函数并获取最后一个节点。

将此项目的“下一个”链接设置为指向新的人,这样新的 人成为列表中的最后一项(即新人应该 有一个 NULL 的“下一个”链接)

从你上面提供的代码来看,我相信你知道如何做到这一点。

【讨论】:

  • 嘿赛格!感谢您的意见。这真的很清楚,很直接。我的代码现在可以编译,但由于某种原因,我遇到了分段错误。我在调用方法 insert_end int i 时得到了; for (i =0; i
  • 顺便说一句,我根据您的建议更新了我的代码。
  • @Sarah 当尝试访问无法访问的内存时,通常会发生分段错误。通常,在实现链表时,当您尝试访问节点的成员 NULL 时会发生这种情况。查看您的代码并密切注意可能出现循环超出范围的实例。
  • @Sarah 顺便说一句,我无法确定您的分段错误错误,除非我拥有您的所有代码。如果需要,您可以通过我的个人资料页面上的电子邮件给我发送电子邮件。
猜你喜欢
  • 2012-10-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-31
  • 1970-01-01
相关资源
最近更新 更多