Path: csiph.com!x330-a1.tempe.blueboxinc.net!usenet.pasdenom.info!news.dougwise.org!nntpfeed.proxad.net!proxad.net!feeder1-2.proxad.net!74.125.46.80.MISMATCH!postnews.google.com!news2.google.com!Xl.tags.giganews.com!border1.nntp.dca.giganews.com!nntp.giganews.com!local2.nntp.dca.giganews.com!nntp.earthlink.com!news.earthlink.com.POSTED!not-for-mail NNTP-Posting-Date: Tue, 05 Jul 2011 00:04:26 -0500 Message-ID: <4E129B5E.6318@mindspring.com> Date: Tue, 05 Jul 2011 01:04:30 -0400 From: pete Reply-To: pfiland@mindspring.com Organization: PF X-Mailer: Mozilla 3.04Gold (WinNT; I) MIME-Version: 1.0 Newsgroups: comp.lang.c Subject: Re: Linked-list problem - compiles but segfaults References: <0ae24ce7-2bd8-4493-989b-0df3bd0ff263@g12g2000yqd.googlegroups.com> <4E128F5A.157A@mindspring.com> Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Lines: 279 X-Usenet-Provider: http://www.giganews.com NNTP-Posting-Host: 4.156.231.76 X-Trace: sv3-TBNVKzjLucM+e3dl4YZfSQFGcsrlmr5vmQw1Q+nSo2I7ueodMI0/rCy4dMb5qpFTQtkFkkvbU2uBoDK!rGC1GUAGQ9OAuEuFcwepjW9QciizNnSVVTkBb7QVvOUMPqDAwM4ZvJwDpRgn0BQOevT653nIRFgX!8tTo86b4aw== X-Abuse-and-DMCA-Info: Please be sure to forward a copy of ALL headers X-Abuse-and-DMCA-Info: Otherwise we will be unable to process your complaint properly X-Postfilter: 1.3.40 X-Original-Bytes: 7850 Xref: x330-a1.tempe.blueboxinc.net comp.lang.c:7647 Andy Elvey wrote: > > On Jul 5, 4:13 pm, pete wrote: > > Andy Elvey wrote: > > > > > Hi all - > > > I've been poking around with C for a while, but I have big problems > > > with linked lists. This seems to be mainly around the "declaration, > > > initialisation, iterating" area. Anyway, I have the code below, which > > > compiles but gives a segfault (and I have no idea why), so hoping that > > > someone may be able to help. > > > ( I have three puts statements at the end because I'm unsure how to > > > iterate along a list. ) > > > [code] > > > /* This code is released to the public domain */ > > > #include > > > #include > > > #include > > > #include > > > #include > > > > > /* Linked list implementation */ > > > typedef struct _List List; > > > > > struct _List { > > > void *data; > > > List *next; > > > }; > > > > > static List *list_malloc (void) > > > { > > > return (List *) malloc (sizeof (List)); > > > } > > > > > List *list_prepend (List *list, void *data) > > > { > > > List *ret = list_malloc (); > > > ret->data = data; > > > ret->next = list; > > > return ret; > > > } > > > > > List *list_append (List *list, void *data) > > > { > > > List *ret; > > > if (list == NULL) return list_prepend (list, data); > > > ret = list; > > > for (; list->next; list = list->next); > > > list->next = list_malloc (); > > > list->next->data = data; > > > list->next->next = NULL; > > > return ret; > > > } > > > > > void list_free (List *list) > > > { > > > List *next; > > > while (list) > > > { > > > next = list->next; > > > free (list); > > > list = next; > > > } > > > } > > > > > /* End linked list implementation */ > > > > > int main() > > > { > > > /* Declare a list */ > > > List *mylist = NULL; > > > list_append(mylist, "foo"); > > > puts(mylist->data); > > > list_append(mylist, (int*) 42); > > > puts(mylist->data); > > > list_append(mylist, "baz"); > > > puts(mylist->data); > > > return 0; > > > } > > > [/code] > > > Very many thanks if you can get this code working...... :) > > > - Andy > > > > /* BEGIN new.c */ > > > > #include > > #include > > #include > > > > /* Linked list implementation */ > > typedef struct LIST { > > struct LIST *next; > > void *data; > > > > } List; > > > > List * > > list_append(List **head, > > List *tail, > > const void *data, > > size_t size) > > { > > List *node; > > > > node = malloc(sizeof *node); > > if (node != NULL) { > > node -> next = NULL; > > node -> data = malloc(size); > > if (node -> data != NULL) { > > memcpy(node -> data, data, size); > > if (*head != NULL) { > > tail -> next = node; > > } else { > > *head = node; > > } > > } else { > > free(node); > > node = NULL; > > } > > } > > return node; > > > > } > > > > void > > list_free(List *node, void (*free_data)(void *)) > > { > > List *next_node; > > > > while (node != NULL) { > > next_node = node -> next; > > free_data(node -> data); > > free(node); > > node = next_node; > > } > > > > } > > > > int > > list_fputs(List *node, FILE *stream) > > { > > int rc = 0; > > > > while (node != NULL > > && (rc = fputs(node -> data, stream)) != EOF > > && (rc = putc( '\n', stream)) != EOF) > > { > > node = node -> next; > > } > > return rc; > > > > } > > > > /* End linked list implementation */ > > > > int > > main(void) > > { > > /* Declare a list */ > > List *mylist = NULL; > > List *tail = NULL; > > char *w[] = {"foo", "bar", "bazooka"}; > > char **p = w; > > > > do { > > tail = list_append(&mylist, tail, *p, 1 + strlen(*p)); > > } while(tail != NULL && ++p != w + sizeof w / sizeof *w); > > puts("/* BEGIN new.c output */\n"); > > list_fputs(mylist, stdout); > > list_free(mylist, free); > > puts("\n/* END new.c output */"); > > return 0; > > > > } > > > > /* END new.c */ > > > > -- > > pete > > Many thanks for that, Pete! That code is the best that I've seen for > a linked list! > It's good to see some code that's easy to understand. > Thanks again - bye for now - You're welcome. You can also use the same list_append() and list_free() functions for other data types as well. /* BEGIN new.c */ #include #include #include /* Linked list implementation */ typedef struct LIST { struct LIST *next; void *data; } List; List * list_append(List **head, List *tail, const void *data, size_t size) { List *node; node = malloc(sizeof *node); if (node != NULL) { node -> next = NULL; node -> data = malloc(size); if (node -> data != NULL) { memcpy(node -> data, data, size); if (*head != NULL) { tail -> next = node; } else { *head = node; } } else { free(node); node = NULL; } } return node; } void list_free(List *node, void (*free_data)(void *)) { List *next_node; while (node != NULL) { next_node = node -> next; free_data(node -> data); free(node); node = next_node; } } int list_int_fprintf(List *node, FILE *stream) { int rc = 0; while (node != NULL && (rc = fprintf(stream, "%d\n", *(int *)node->data)) > 0) { node = node -> next; } return rc; } /* End linked list implementation */ int main(void) { /* Declare a list */ List *mylist = NULL; List *tail = NULL; int i[] = {1, 2, 42}; int *p = i; do { tail = list_append(&mylist, tail, p, sizeof *p); } while(tail != NULL && ++p != i + sizeof i / sizeof *i); puts("/* BEGIN new.c output */\n"); list_int_fprintf(mylist, stdout); list_free(mylist, free); puts("\n/* END new.c output */"); return 0; } /* END new.c */ -- pete