| Summary: | LIST_*, TAILQ_* man pages include memory leak in sample code | ||
|---|---|---|---|
| Product: | Documentation | Reporter: | David Leppik <dleppik> |
| Component: | Books & Articles | Assignee: | freebsd-doc (Nobody) <doc> |
| Status: | Closed FIXED | ||
| Severity: | Affects Only Me | ||
| Priority: | Normal | ||
| Version: | Latest | ||
| Hardware: | Any | ||
| OS: | Any | ||
On Sunday 16 October 2005 05:50 pm, David Leppik wrote: > >Number: 87548 > >Category: docs > >Synopsis: LIST_*, TAILQ_* man pages include memory leak in sample > > code Confidential: no > >Severity: non-critical > >Priority: low > >Responsible: freebsd-doc > >State: open > >Quarter: > >Keywords: > >Date-Required: > >Class: doc-bug > >Submitter-Id: current-users > >Arrival-Date: Sun Oct 16 22:00:27 GMT 2005 > >Closed-Date: > >Last-Modified: > >Originator: David Leppik > >Release: None (old BSD code--see below) > >Organization: > > Vocal Laboratories > > >Environment: > >Description: > > I've seen this on Mac OS X and Linux, so this probably affects FreeBSD as > well. > > The man page for TAILQ_INSERT, TAILQ_REMOVE, etc. have the following sample > code: > > while (head.tqh_first != NULL) > TAILQ_REMOVE(&head, head.tqh_first, entries); > > I was so shocked that I checked queue.h and sure enough, TAILQ_REMOVE does > not deallocate the queue entry (nor should it.) The same is true for the > other structures mentioned in this man page. > > >How-To-Repeat: > > > >Fix: > > I'm just a lowly Java programmer, but I think the fix is: > > while (head.tqh_first != NULL) { > np = head.tqh_first; > TAILQ_REMOVE(&head, np, entries); > free(np); > } > Well, it should be something like: while (!TAILQ_EMPTY(&head)) { np = TAILQ_FIRST(&head); TAILQ_REMOVE(&head, np, entries); free(np); } And actually, on my machine here running current this is what the examples look like: /* TailQ Deletion. */ while (!TAILQ_EMPTY(&head)) { n1 = TAILQ_FIRST(&head); TAILQ_REMOVE(&head, n1, entries); free(n1); } /* Faster TailQ Deletion. */ n1 = TAILQ_FIRST(&head); while (n1 != NULL) { n2 = TAILQ_NEXT(n1, entries); free(n1); n1 = n2; } TAILQ_INIT(&head); Which version of FreeBSD are you seeing the memory leak in? -- John Baldwin <jhb@FreeBSD.org> <>< http://www.FreeBSD.org/~jhb/ "Power Users Use the Power to Serve" = http://www.FreeBSD.org State Changed From-To: open->closed The queue(3) manual page on FreeBSD has had the calls to free() in place since revision 1.2 added them back in January of 1996. :) |
I've seen this on Mac OS X and Linux, so this probably affects FreeBSD as well. The man page for TAILQ_INSERT, TAILQ_REMOVE, etc. have the following sample code: while (head.tqh_first != NULL) TAILQ_REMOVE(&head, head.tqh_first, entries); I was so shocked that I checked queue.h and sure enough, TAILQ_REMOVE does not deallocate the queue entry (nor should it.) The same is true for the other structures mentioned in this man page. Fix: I'm just a lowly Java programmer, but I think the fix is: while (head.tqh_first != NULL) { np = head.tqh_first; TAILQ_REMOVE(&head, np, entries); free(np); }