ç圆形双链表:遍历FWD / REV为最终节点提供了不同的指针地址 [英] c circular double linked-list: traverses fwd/rev for end node gives different pointer address

查看:148
本文介绍了ç圆形双链表:遍历FWD / REV为最终节点提供了不同的指针地址的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

相关岗位:<一href=\"http://stackoverflow.com/questions/22576064/c-circular-double-linked-list-delete-node-iterate-traverses-deleted-node-on-fi\">c圆形双链表delete_node - 迭代横贯删除节点上第一遍删除后

所有之前,删除该节点实施为节点contianing行号的x进行搜索,我穿过其中两个正向和反向的搜索识别正确的节点的一个问题跑,但是对于呼叫者的节点地址的指针被报告不同由比正向反向搜索?这仅适用于最后一个节点(hightest行号)。如果只forwrd搜索时(pba_fwd_iter_test),则最后一个节点被正确删除。然而,如果向后搜索时(pba_rev_iter_test),然后通过设置的地址(被害人>下) - > preV =受害者 - > $ P $光伏;不正确,它集(被害人>旁边) - > preV =(被害人>旁边) - > preV。例如,到达与反向搜索结束节点,然后preforming的delete_node结果如下:

  49:7  - (行删除)这是一个文本行的长度大概在他50到80个字符48  -  preV:0x604a80 CUR:0x604b10下一:0x604ba0
49 - preV:0x604b10 CUR:0x604ba0下一:0x603010&LT; - delete_node
 0 - preV:0x604ba0 CUR:0x603010下一个:0x6030a048 - preV:0x604a80 CUR:0x604b10下一:0x603010
49 - preV:0x604b10 CUR:0x604ba0下一:0x603010&LT; - (节点删除)
 0 - preV:0x603010 CUR:0x603010下一个:0x6030a0
              \\ _______________ \\ ______错误(应该是preV:0x604b10)

@WhosCraig慷慨地与delete_node功能的正常工作帮助,但为什么与在delete_node未设置(被害人>旁)反向搜索结果定位在同一个节点时,我想不通 - > preV =受害者 - > preV;正常。作为反向搜索的考验,我只是踩朝开始一个额外的节点,然后向前走去一个节点返回到有问题的节点,然后delete_node工作的罚款。 (只是一个补充:列表=及(*名单) - > preV;列表=及(*名单) - >接下来;.所以这个问题已经是与指针状态下给最终到达时,与反向搜索,而不是向前SEACH节点 - 这就是我需要帮助搞清楚这里是指针地址以下正向和反向searchs输出,以及之后的快速 - > preV - >下一篇:

  =========== pba_fwd_iter_test()===========
传递列表=及(*列表) - &gt;接着,以tstpptr(0x605b28)
tstpptr():名单:0x605b28
tstpptr():放大器;清单:0x7ffff14633a8
tstpptr():*列表:0x605ba0
tstpptr()及(*列表):0x605b28&LT; - 报道调用者的地址
tstpptr():及(**列表):0x605ba0与向前搜索tstpptr()及(*名单) - &gt;接下来:0x605bb8=========== pba_rev_iter_test()===========
传递列表=及(*列表) - &gt;接着,以tstpptr(0x604020)
tstpptr():名单:0x604020
tstpptr():放大器;清单:0x7ffff14633a8
tstpptr():*列表:0x605ba0
tstpptr()及(*列表):0x604020&LT; - 来电者的地址报道
tstpptr():及(**列表):0x605ba0反向搜索tstpptr()及(*名单) - &gt;接下来:0x605bb8传递列表=及(*列表) - &gt;接着,以tstpptr(0x605b28)
tstpptr():名单:0x605b28
tstpptr():放大器;清单:0x7ffff14633a8
tstpptr():*列表:0x605ba0
tstpptr()及(*列表):0x605b28&LT; - 后来电者的地址报道
tstpptr():及(**列表):0x605ba0及(*列表) - &GT; $ P $光伏;及(*列表) - &gt;接着tstpptr()及(*名单) - &gt;接下来:0x605bb8

下面是用在开头的链接全部源代码相关的code片段。谢谢你的任何帮助,您可以提供:

  / *
完整的源:http://www.3111skyline.com/dl/dev/prg/src/ll-double-cir-1.c.txt
* /结构记录
{
字符*线;
INT LINENO;
INT线型;
结构记录* preV;
结构记录*旁边;
};
typedef结构记录REC;在FWD方向无效//遍历找到hightest号线。
pba_fwd_iter_test(REC **名单,INT NUM);
无效//遍历单位转方向寻找hightest号线。
pba_rev_iter_test(REC **名单,INT NUM);
无效//转储指针检查
tstpptr(REC **清单);INT主(INT ARGC,CHAR *的argv []){
//&LT;&剪断GT; 50条记录填写结构测试(LINENO'0'基于0-49)
pba_fwd_iter_test(安培;文本文件,49);
pba_rev_iter_test(安培;文本文件,49);
返回0;
}空虚
pba_fwd_iter_test(REC **名单,INT NUM){
的printf(%=========== S()=========== \\ n,__ func__);
INT linemax = getmaxline(*清单);
INT iterno = 0;
而(((*列表) - &GT;!LINENO = NUM​​)及及(iterno&下; = linemax)){
    iterno ++;
    列表=及(*名单) - &gt;接下来,
}
的printf(合格名单=及(*名单) - &gt;接下来到tstpptr(%P)\\ n,清单);
tstpptr(名单);
}空虚
pba_rev_iter_test(REC **名单,INT NUM){
的printf(%=========== S()=========== \\ n,__ func__);
INT linemax = getmaxline(*清单);
INT iterno = 0;
而(((*列表) - &GT;!LINENO = NUM​​)及及(iterno&下; = linemax)){
    iterno ++;
    列表=及(*名单) - GT; preV;
}
的printf(合格名单=及(*名单) - &gt;接下来到tstpptr(%P)\\ n,清单);
tstpptr(名单);
//增量$ P $光伏然后下一个,并再次检查PTR值
列表=及(*名单) - GT; preV;
列表=及(*名单) - &gt;接下来,
的printf(合格名单=及(*名单) - &gt;接下来到tstpptr(%P)\\ n,清单);
tstpptr(名单);
}空虚
tstpptr(REC **名单){
fprintf中(标准输出,%S():列表:%P \\ N,__func__,清单);
fprintf中(标准输出,%S():放大器;清单:%P \\ N,__func__,&安培;清单);
fprintf中(标准输出,%S():*列表:%P \\ N,__func__,*名单);
fprintf中(标准输出,%S()及(*列表):%P \\ N,__func__,及(*列表));
fprintf中(标准输出,%S()及(**列表):%P \\ n \\ n,__func__,及(**列表));
fprintf中(标准输出,%S()及(*名单) - &gt;接下来:%P \\ n \\ n,__func__,及(*名单) - &gt;接着);
}


解决方案

我想我看到的问题 - 我不认为有一个。最重要的值是 *名单,这是在所有情况下是相同的。我想打印出清单,并与放大器;列表等等仅仅是混浊的问题

在你的前向迭代器,列表指向的项目#48的接下来变量的位置。

在你落后的迭代器,列表指向的项目#0 $ P $光伏变量的位置。

在这两种情况下*目录指向正确的项目#49。

这两个函数就会简单得多,如果他们只花了 REC * ,而不是录音** ,那么这将是比较明显的,服用列表变量的地址是不是你想要的。

related post: c circular double linked-list delete_node - iterate traverses deleted node on first pass after delete

All, implementing a search for node contianing line number 'x' prior to deleting that node, I ran across a problem where both forward and reverse searches identify the proper node, but the pointer for the caller's node address is reported differently by the reverse search than for the forward? This applies to the last node (hightest line number) only. If only the forwrd search is used (pba_fwd_iter_test), then the last node is deleted properly. However, if the reverse search is used (pba_rev_iter_test), then the address set by "(victim->next)->prev = victim->prev;" is incorrect, it sets "(victim->next)->prev = (victim->next)->prev". For example, arriving at the end node with a reverse search and then preforming the delete_node results in the following:

49: 7 - (line to delete) This is a line of text that is somewhere around 50 to 80 characters in length

48 - prev: 0x604a80  cur: 0x604b10  next: 0x604ba0
49 - prev: 0x604b10  cur: 0x604ba0  next: 0x603010  <-- delete_node
 0 - prev: 0x604ba0  cur: 0x603010  next: 0x6030a0

48 - prev: 0x604a80  cur: 0x604b10  next: 0x603010
49 - prev: 0x604b10  cur: 0x604ba0  next: 0x603010  <-- (node deleted)
 0 - prev: 0x603010  cur: 0x603010  next: 0x6030a0
              \_______________\______ Error (should be prev: 0x604b10)

@WhosCraig graciously helped with the delete_node function which works fine, but I cannot figure out why when locating the same node with the reverse search results in the delete_node failing to set "(victim->next)->prev = victim->prev;" properly. As a test of the reverse search, I simply stepped one additional node toward the beginning and then went forward one node back to the node in question and then the delete_node worked fine. (simply an additional: list = &(*list)->prev; list = &(*list)->next;. So the issue has something to do with the pointer state when arriving at the end-node with a reverse search rather than a forward seach -- that is what I need help figuring out. Here is the output of the pointer addresses following both forward and reverse searchs, as well as following the quick ->prev ->next:

=========== pba_fwd_iter_test() ===========
passing list = &(*list)->next to tstpptr (0x605b28)
tstpptr(): list     : 0x605b28
tstpptr(): &list    : 0x7ffff14633a8
tstpptr(): *list    : 0x605ba0
tstpptr(): &(*list) : 0x605b28  <- caller's address reported
tstpptr(): &(**list): 0x605ba0     with forward search

tstpptr(): &(*list)->next : 0x605bb8

=========== pba_rev_iter_test() ===========
passing list = &(*list)->next to tstpptr (0x604020)
tstpptr(): list     : 0x604020
tstpptr(): &list    : 0x7ffff14633a8
tstpptr(): *list    : 0x605ba0
tstpptr(): &(*list) : 0x604020  <- caller's address reported
tstpptr(): &(**list): 0x605ba0     with reverse search

tstpptr(): &(*list)->next : 0x605bb8

passing list = &(*list)->next to tstpptr (0x605b28)
tstpptr(): list     : 0x605b28
tstpptr(): &list    : 0x7ffff14633a8
tstpptr(): *list    : 0x605ba0
tstpptr(): &(*list) : 0x605b28  <- caller's address reported after
tstpptr(): &(**list): 0x605ba0     &(*list)->prev; &(*list)->next

tstpptr(): &(*list)->next : 0x605bb8

The following are the relevant code snippets with the link to the full source at the beginning. Thank you for any help you can provide:

/*
full source: http://www.3111skyline.com/dl/dev/prg/src/ll-double-cir-1.c.txt
*/

struct record
{
char *line;
int lineno;
int linetype;
struct record *prev;
struct record *next;
};
typedef struct record rec;

void  // traverse in fwd direction to find hightest line no.
pba_fwd_iter_test (rec **list, int num);
void  // traverse in rev direction to find hightest line no.
pba_rev_iter_test (rec **list, int num);
void  // dump the pointers for examination
tstpptr (rec **list);

int main (int argc, char *argv[]) {
// <snip> fill struct with 50 records for testing (lineno '0' based 0-49)
pba_fwd_iter_test (&textfile, 49);
pba_rev_iter_test (&textfile, 49);
return 0;
}

void
pba_fwd_iter_test (rec **list, int num) {
printf ("=========== %s() ===========\n",__func__);
int linemax = getmaxline (*list);
int iterno = 0;
while (((*list)->lineno != num) && (iterno <= linemax)) {
    iterno++;
    list = &(*list)->next;
}
printf ("passing list = &(*list)->next to tstpptr (%p)\n", list);
tstpptr (list);
}

void
pba_rev_iter_test (rec **list, int num) {
printf ("=========== %s() ===========\n",__func__);
int linemax = getmaxline (*list);
int iterno = 0;
while (((*list)->lineno != num) && (iterno <= linemax)) {
    iterno++;
    list = &(*list)->prev;
}
printf ("passing list = &(*list)->next to tstpptr (%p)\n", list);
tstpptr (list);
// increment prev then next and check ptr values again
list = &(*list)->prev;
list = &(*list)->next;
printf ("passing list = &(*list)->next to tstpptr (%p)\n", list);
tstpptr (list);
}

void
tstpptr (rec **list) {
fprintf (stdout, "%s(): list      : %p\n", __func__, list);
fprintf (stdout, "%s(): &list     : %p\n", __func__, &list);
fprintf (stdout, "%s(): *list     : %p\n", __func__, *list);
fprintf (stdout, "%s(): &(*list)  : %p\n", __func__, &(*list));
fprintf (stdout, "%s(): &(**list) : %p\n\n", __func__, &(**list));
fprintf (stdout, "%s(): &(*list)->next : %p\n\n", __func__, &(*list)->next);
}

解决方案

I think I see the problem - I don't think there is one. The important value is *list, which is the same in all cases. I think printing out list and &list etc is just clouding the issue.

In your forward iterator, list is pointing to the location of item #48's next variable.

In your backward iterator, list is pointing to the location of item #0's prev variable.

In both cases *list is pointing to the correct item #49.

Both functions would be much simpler if they just took a rec *, rather than a rec **, then it would be more obvious that taking the address of the list variable isn't what you want.

这篇关于ç圆形双链表:遍历FWD / REV为最终节点提供了不同的指针地址的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆