iterator - c circular double linked-list: traverses fwd/rev for end node gives different pointer address -
related post: c circular double linked-list delete_node - iterate traverses deleted node on first pass after delete
all, implementing search node contianing line number 'x' prior deleting node, ran across problem both forward , reverse searches identify proper node, pointer caller's node address reported differently reverse search forward? applies last node (hightest line number) only. if forwrd search used (pba_fwd_iter_test), last node deleted properly. however, if reverse search used (pba_rev_iter_test), address set "(victim->next)->prev = victim->prev;" incorrect, sets "(victim->next)->prev = (victim->next)->prev". example, arriving @ end node reverse search , preforming delete_node results in following:
49: 7 - (line delete) line of text somewhere around 50 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 prev: 0x604b10) @whoscraig graciously helped delete_node function works fine, cannot figure out why when locating same node reverse search results in delete_node failing set "(victim->next)->prev = victim->prev;" properly. test of reverse search, stepped 1 additional node toward beginning , went forward 1 node node in question , delete_node worked fine. (simply additional: list = &(*list)->prev; list = &(*list)->next;. issue has pointer state when arriving @ end-node reverse search rather forward seach -- need figuring out. here output of pointer addresses following both forward , reverse searchs, following quick ->prev ->next:
=========== pba_fwd_iter_test() =========== passing list = &(*list)->next tstpptr (0x605b28) tstpptr(): list : 0x605b28 tstpptr(): &list : 0x7ffff14633a8 tstpptr(): *list : 0x605ba0 tstpptr(): &(*list) : 0x605b28 <- caller's address reported tstpptr(): &(**list): 0x605ba0 forward search tstpptr(): &(*list)->next : 0x605bb8 =========== pba_rev_iter_test() =========== passing list = &(*list)->next tstpptr (0x604020) tstpptr(): list : 0x604020 tstpptr(): &list : 0x7ffff14633a8 tstpptr(): *list : 0x605ba0 tstpptr(): &(*list) : 0x604020 <- caller's address reported tstpptr(): &(**list): 0x605ba0 reverse search tstpptr(): &(*list)->next : 0x605bb8 passing list = &(*list)->next 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 relevant code snippets link full source @ beginning. thank 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 find hightest line no. pba_fwd_iter_test (rec **list, int num); void // traverse in rev direction find hightest line no. pba_rev_iter_test (rec **list, int num); void // dump pointers examination tstpptr (rec **list); int main (int argc, char *argv[]) { // <snip> fill struct 50 records 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 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 tstpptr (%p)\n", list); tstpptr (list); // increment prev next , check ptr values again list = &(*list)->prev; list = &(*list)->next; printf ("passing list = &(*list)->next 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 see problem - don't think there one. important value *list, same in cases. think printing out list , &list etc clouding issue.
in forward iterator, list pointing location of item #48's next variable.
in backward iterator, list pointing location of item #0's prev variable.
in both cases *list pointing correct item #49.
both functions simpler if took rec *, rather rec **, more obvious taking address of list variable isn't want.
Comments
Post a Comment