[荐]Linux C编程连载(5)- 关于双链表“掉链子”的问题

 【问题】用双链表实现贪吃蛇时,用gcc编译后,执行发生段错误。用gdb调试发现错误位于删除操作,后检查发现真正的原因出在插入操作。如题所示,双链表掉链子了,没接上。

【分析】

如图1所示,在插入C之前,A和B节点是链接的,现在要在节点A和B节点之间插入一节点C,参照教科书的算法如下:

(1) C->prev=A

(2) C->next=B

(3) A->next=C

(4) B->prev=C

错误代码实现如下:

node *C = (node *)malloc(sizeof(node));

C->prev = A;//step 1

C->next = A->next;//step 2

A->next= C;//step 3

A->next->prev = C;//step 4


 

上述代码step 4就是导致段错误的“真凶”。下面具体分析为什么错了:

在插入C节点前,A->next = B(表示A->next指向B)是成立的。但执行步骤3后,A->next链子断开了,此时A->next=C,即A->next指向了C,此时再用A->next->prev = C,就相当于C->prev = C。图1所示操作4显然没有实现,双链表B->prev=C “掉链子"了。有趣的是,gdb调试时常找不到段错误真正的原因。

如何修改?

很简单,改为C->next->prev=C或者A->next->next->prev = C就可以了。

图1 双链表插入操作(1)

如图2所示,下面我们改变链接的顺序,看看代码有和变化。

step 1 B->prev=C

此时A->next=B成立,故

A->next->prev=C;

step 2 C->prev=A

C->prev=A

step 3 C->next=B,经过step1,2后,B->prev链子断开了,但A->next链子没有断开,此时A->next=B仍成立【注:此前发布的博文,此处有错误,修改时间2011-11-18

C->next=A->next;

step 4 A->next=C

A->next=C

 

图2 双链表插入操作(2)

 

【双链表操作原则】节点A和B相互链接,保证A->next=B,B->prev=A。

无论进行何种操作,都要保证相互链接的节点满足上述原则。

 

 

转载请标明出处,仅供学习交流,勿用于商业目的

Copyright @ http://blog.csdn.net/tandesir

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值