Reputation: 11
I'm trying to implement a Barnes-Hutt tree in C and I'm having an issue when freeing the tree.
The nodes in the tree are as follows:
struct node {
int is_external;
quad q;
body *b;
node *nw;
node *ne;
node *sw;
node *se;
};
and the function I use to free them is
void free_node(node *n) {
// free subnodes
if (n->nw != NULL) {
free_node(n->nw);
}
if (n->ne != NULL) {
free_node(n->ne);
}
if (n->sw != NULL) {
free_node(n->sw);
}
if (n->se != NULL) {
free_node(n->se);
}
// free this node's body
if (!n->is_external) {
free(n->b);
}
free(n);
}
(I'm not freeing the bodies of external nodes because they are kept for the next iteration of the simulation).
When I check for memory leaks however, I get
72 bytes in 1 blocks are definitely lost in loss record 24 of 51
at 0x100111CF5: malloc (in /usr/local/Cellar/valgrind/HEAD-9f4f524/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
by 0x100001B95: subnode (bh_tree.c:70)
by 0x100002413: insert_in_node (bh_tree.c:165)
by 0x100001693: main (sim.c:115)
72 bytes in 1 blocks are definitely lost in loss record 25 of 51
at 0x100111CF5: malloc (in /usr/local/Cellar/valgrind/HEAD-9f4f524/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
by 0x100001B95: subnode (bh_tree.c:70)
by 0x100001E64: insert_in_node (bh_tree.c:108)
by 0x100002675: insert_in_node (bh_tree.c:188)
by 0x100001693: main (sim.c:115)
72 bytes in 1 blocks are definitely lost in loss record 26 of 51
at 0x100111CF5: malloc (in /usr/local/Cellar/valgrind/HEAD-9f4f524/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
by 0x100001B95: subnode (bh_tree.c:70)
by 0x10000251D: insert_in_node (bh_tree.c:173)
by 0x100001F97: insert_in_node (bh_tree.c:118)
by 0x100001693: main (sim.c:115)
72 bytes in 1 blocks are definitely lost in loss record 27 of 51
at 0x100111CF5: malloc (in /usr/local/Cellar/valgrind/HEAD-9f4f524/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
by 0x100001B95: subnode (bh_tree.c:70)
by 0x100002627: insert_in_node (bh_tree.c:181)
by 0x10000209B: insert_in_node (bh_tree.c:126)
by 0x100002675: insert_in_node (bh_tree.c:188)
by 0x100001F97: insert_in_node (bh_tree.c:118)
by 0x100001693: main (sim.c:115)
72 bytes in 1 blocks are definitely lost in loss record 28 of 51
at 0x100111CF5: malloc (in /usr/local/Cellar/valgrind/HEAD-9f4f524/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
by 0x100001B95: subnode (bh_tree.c:70)
by 0x10000206C: insert_in_node (bh_tree.c:124)
by 0x100002675: insert_in_node (bh_tree.c:188)
by 0x10000209B: insert_in_node (bh_tree.c:126)
by 0x100002675: insert_in_node (bh_tree.c:188)
by 0x100001F97: insert_in_node (bh_tree.c:118)
by 0x100001693: main (sim.c:115)
72 bytes in 1 blocks are definitely lost in loss record 29 of 51
at 0x100111CF5: malloc (in /usr/local/Cellar/valgrind/HEAD-9f4f524/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
by 0x100001B95: subnode (bh_tree.c:70)
by 0x100002170: insert_in_node (bh_tree.c:132)
by 0x100001693: main (sim.c:115)
72 bytes in 1 blocks are definitely lost in loss record 30 of 51
at 0x100111CF5: malloc (in /usr/local/Cellar/valgrind/HEAD-9f4f524/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
by 0x100001B95: subnode (bh_tree.c:70)
by 0x100002627: insert_in_node (bh_tree.c:181)
by 0x100001E93: insert_in_node (bh_tree.c:110)
by 0x100001693: main (sim.c:115)
72 bytes in 1 blocks are definitely lost in loss record 31 of 51
at 0x100111CF5: malloc (in /usr/local/Cellar/valgrind/HEAD-9f4f524/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
by 0x100001B95: subnode (bh_tree.c:70)
by 0x100002627: insert_in_node (bh_tree.c:181)
by 0x10000219F: insert_in_node (bh_tree.c:134)
by 0x100002675: insert_in_node (bh_tree.c:188)
by 0x100001E93: insert_in_node (bh_tree.c:110)
by 0x100001693: main (sim.c:115)
72 bytes in 1 blocks are definitely lost in loss record 32 of 51
at 0x100111CF5: malloc (in /usr/local/Cellar/valgrind/HEAD-9f4f524/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
by 0x100001B95: subnode (bh_tree.c:70)
by 0x100002309: insert_in_node (bh_tree.c:157)
by 0x10000219F: insert_in_node (bh_tree.c:134)
by 0x100002675: insert_in_node (bh_tree.c:188)
by 0x10000219F: insert_in_node (bh_tree.c:134)
by 0x100002675: insert_in_node (bh_tree.c:188)
by 0x100001E93: insert_in_node (bh_tree.c:110)
by 0x100001693: main (sim.c:115)
72 bytes in 1 blocks are definitely lost in loss record 33 of 51
at 0x100111CF5: malloc (in /usr/local/Cellar/valgrind/HEAD-9f4f524/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
by 0x100001B95: subnode (bh_tree.c:70)
by 0x10000206C: insert_in_node (bh_tree.c:124)
by 0x100002675: insert_in_node (bh_tree.c:188)
by 0x10000219F: insert_in_node (bh_tree.c:134)
by 0x100002675: insert_in_node (bh_tree.c:188)
by 0x10000219F: insert_in_node (bh_tree.c:134)
by 0x100002675: insert_in_node (bh_tree.c:188)
by 0x100001E93: insert_in_node (bh_tree.c:110)
by 0x100001693: main (sim.c:115)
all of which point to the following malloc
node n_sub;
n_sub.is_external = 1;
n_sub.q = subquad(n.q, k);
n_sub.nw = NULL;
n_sub.ne = NULL;
n_sub.sw = NULL;
n_sub.se = NULL;
n_sub.b = malloc(sizeof(body));
*n_sub.b = (body) {.id=EMPTY};
return n_sub;
}
but I'm fairly certain I was freeing all of these correctly. Any ideas where it could be going wrong?
Upvotes: 0
Views: 102
Reputation: 70442
Apparently valgrind
is always complaining about the same malloc
:
at 0x100111CF5: malloc (
...)
by 0x100001B95: subnode (bh_tree.c:70)
And the only malloc
you point to in your code is at a guess the implementation of subnode
:
node n_sub;
n_sub.is_external = 1;
//...
n_sub.b = malloc(sizeof(body));
But, in your free_node
function you only call free
if is_external
is false:
if (!n->is_external) {
free(n->b);
}
So, you need to suspect whatever code path you think is setting is_external
to false is not always (or perhaps is never) called.
Upvotes: 2