将新节点添加到列表时出现分段错误

时间:2015-07-31 12:32:45

标签: c list

我在搜索列表并尝试添加新节点时遇到问题。 该守则如下:

struct sizelist{
    int currentsize, origsize;
    struct sizelist * next;
};
typedef struct sizelist item;

以下是内容的大小,items是连接的节点数量,next是下一个节点。

void firstfit(item tosort){
  int junksize = tosort.currentsize;
  int paired;
  item* current;
  for(int i=0;i<containeramount;i++){
    if(containers[i].currentsize - junksize >=0){
      paired = i;
      break;
    }
  }
  current = &containers[paired];
  while(current->next!=NULL){
    current = current->next;
  }
  containers[paired].currentsize = containers[paired].currentsize - junksize;
  current->next = &tosort;
 }

containersitem的数组。

这似乎现在有效。但现在我的输出有问题:

void writeout(){
  item* current;
  for(int i=0;i<containeramount;i++){
    current = &containers[i];
    for(int j=0;; j++){
      printf("%d ",current->currentsize);
      if(current->next!=NULL){
        current = current->next;
      }
      else{
        break;
      }
    }
    printf("\n");
  }
}

现在你也有了解这个程序。 我给它举例说明了3个容量为10的容器,以及尺寸为6,8,1,5的东西。看起来firstfit使它成为可能,但writeout方法却没有。 这里适当的输出应该是:

10 6 1

10 8

10 5

这里origsize的输出是:

10 3

10 3

10 3

对于大潮来说,它是:

3 134515941

2 134515941

5 134515941

1 个答案:

答案 0 :(得分:2)

看起来代码的最新版本得到了很大改进, 但tosort按值传递到firstfit(item tosort)。 这意味着在函数firstfit(item tosort)中,tosort是临时的 在函数末尾销毁的变量。 (这也是该计划的早期版本,但我们看了 首先是其他问题。)

现在该功能正在对实际内容进行处理 是containers[paired]而不是临时复制的东西, 正在设置列表中的最终next指针(根据需要), 但它指向临时对象tosort。 当函数结束时,tosort超出范围。 据推测,其他东西被写入同一个虚拟块 当你试图将它打印出来时的记忆。

如果将功能更改为,这将更有效 firstfit(item* tosort),即传递指针而不是副本 结构。 这将表现得更像你期望调用函数 用Java表现。

注意:以下评论参考revision 2 of the question. 此后,问题中的代码已被修改,以便遵循 这些建议。

我在代码中发现了很多明显的错误,很难跟踪 所有这些,但我怀疑分段错误在这里:

    current = containers[paired];
    for(int i=0;i<containers[paired].items;i++){
        current = *current.next;
    }

代码中的一个错误是您声明item current;。 这意味着current始终是临时数据结构,并且永远不会 实际上&#34;在&#34; containers[paired]。执行current.next = &tosort;时,唯一改变的是此临时数据结构的字段,该字段超出下一行的范围并被销毁。所以实际上这条线什么都没做。最明显的是containers[paired]中插入任何数据。

另一方面,containers[paired].items++; 会增加containers[paired]中的计数器。所以现在containers[paired].items大于链表中实际的项目数。这意味着当你在其他时间进入这个函数并使用相同的containers[paired]执行上面的循环时,你将执行current = *current.next;太多次;您最终尝试访问列表中最后一个节点的next节点,然后您进行了段错误。

在C中实现简单链表的标准方法是设置 next指针指向0(或NULL,如果它被定义为0) 没有实际的&#34; next&#34;列表中的东西;列表中的最后一件事 总是 next等于0.为了找到列表中的最后一项, 你不计算跟随next指针的次数; 您只需按照next指针,直到到达其节点 next指针为0,然后停止。

我强烈建议摆脱items。您始终可以通过列表到最后并计算遇到的节点数来找出容器中有多少项。当然,这需要的时间不仅仅是读取items的值,但它会为您提供正确的答案,而不会导致分段错误。让您的程序正常运行,然后您可以考虑在需要时将其设置得更快(例如,将items放回到您的结构中并使其实际具有正确的值。)