Messages in this thread | | | Date | 23 May 97 09:52:37 EDT | From | <> | Subject | SIGSEGV, not a problem just interesting observation. |
| |
Hi guys,
I would like to share with you a curious thing I have just noticed while debugging my program that manipulates doubly-linked lists. The intersting fact is that after I have tested the program successfully on DYNIX/ptx, Digital Unix and IBM AIX I was almost confident that it works fine, but... as soon as I tried it on Linux it mysteriously coredumped (with SIGSEGV). A few minutes of debugging with gdb(1) revealed the following:
struct list { char *text; struct list *prev; struct list *next; };
In the 'traverse' function for doubly-linked list with first element pointed to by 'root':
/* wrong version */ void traverselist(struct list *root, void (*visit)(struct list *p)) { if (root != NULL) { visit(root); traverselist(root->next, visit); } }
/* correct version */ void traverselist(struct list *root, void (*visit)(struct list *p)) { if (root != NULL) { struct list *next = root->next; visit(root); traverselist(next, visit); } }
void freenode(struct list *node) { free(node->text); free(node); }
void freelist(struct list *root) { traverselist(root, freenode); }
Now, when we invoke freelist() on ptx, AIX or Digital everything is fine, but on Linux it coredumps as soon as root->next is referenced after call to visit(root) because visit(root) destroyed the root so we shouldn't really reference it.
Thanks for your attention, Tigran A. Aivazian.
PS. I know that linux-c-programming is more appropriate for this but recently it was flooded with some rubbish by some idiot (lamer@aol.com) so I thought I would wait a bit before sending or receiving anything from linux-c-programming.
PPS. If you have any comments please reply to me directly.
| |