473,786 Members | 2,368 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Unable to deallocate memory for a tree structure.

Hi, I'm trying to deallocate a kd tree which I created dynamically.
There were no problems
creating the structure and I can access it easily but there is a
problem while trying to free
it. Here's the structure for the a single node in the tree:
typedef struct kdnode_s
{
bbox box; /* Bounding box */
int splitplane; /* -1 for leaf node*/
union
{
struct
{
struct kdnode_s *child[2]; /* Children node */
double split;

}nonleaf;

struct
{
size_t nt;
node *thead; /* Link list */

}leaf;

}info;

}kdnode;
Some other supporting data structures :

/* vector */

typedef struct
{
double coord[3];

}vector;

/* bounding box */

typedef struct
{
vector maxB, minB;

}bbox;

/* link list node */

typedef struct node_s
{
struct node_s *next;
void *data;

}node;
Heres the function I wrote to free the kdtree. I pass the address of
the root node pointer
and traverse the tree until I reach a leaf node which is characterised
by splitplane member
being -1. If it is not -1, then it has values 0,1,2 and it is a
nonleaf node. The leaf node
is freed and then I try to free other nodes as I climb back. Once a
leaf node is freed its
pointer is made NULL. This makes it easier to free other nodes once
their children have
been freed.

void free_kd_tree(kd node **kd)
{
if (*kd != NULL)
{
if ((*kd)->splitplane == -1)
{
free_list((*kd)->info.leaf.thea d);
*kd = NULL;
return ;
}
else
{
free_kd_tree(&( *kd)->info.nonleaf.c hild[0]);
free_kd_tree(&( *kd)->info.nonleaf.c hild[1]);

if ((*kd)->info.nonleaf.c hild[0] == NULL &&
(*kd)->info.nonleaf.c hild[1] == NULL)
{
free(*kd);
*kd = NULL;
}
}
}
}

In this program the free_list is a routine to free the link list given
its head pointer and this
is how I wrote it:

void free_list(node *head)
{
node *p;

p = head;
while (p != NULL)
{
free(p);
p = p->next;
}
}

For some reason I observed, the free(p) is not able to execute and the
program terminates
at the point without any warning or message. What could be wrong ?
Jul 6 '08 #1
8 2550
pereges <Br*****@gmail. comwrote:
Hi, I'm trying to deallocate a kd tree which I created dynamically. There
were no problems creating the structure and I can access it easily but
there is a problem while trying to free it. Here's the structure for the a
single node in the tree:
typedef struct kdnode_s
{
bbox box; /* Bounding box */
int splitplane; /* -1 for leaf node*/
union
{
struct
{
struct kdnode_s *child[2]; /* Children node */
double split;
}nonleaf;
struct
{
size_t nt;
node *thead; /* Link list */
}leaf;
}info;
}kdnode;
Some other supporting data structures :
/* vector */
typedef struct
{
double coord[3];
}vector;
/* bounding box */
typedef struct
{
vector maxB, minB;
}bbox;
/* link list node */
typedef struct node_s
{
struct node_s *next;
void *data;
}node;
Heres the function I wrote to free the kdtree. I pass the address of the
root node pointer and traverse the tree until I reach a leaf node which is
characterised by splitplane member being -1. If it is not -1, then it has
values 0,1,2 and it is a nonleaf node. The leaf node is freed and then I
try to free other nodes as I climb back. Once a leaf node is freed its
pointer is made NULL. This makes it easier to free other nodes once their
children have been freed.
void free_kd_tree(kd node **kd)
{
if (*kd != NULL)
{
if ((*kd)->splitplane == -1)
{
free_list((*kd)->info.leaf.thea d);
*kd = NULL;
return ;
}
else
{
free_kd_tree(&( *kd)->info.nonleaf.c hild[0]);
free_kd_tree(&( *kd)->info.nonleaf.c hild[1]);
if ((*kd)->info.nonleaf.c hild[0] == NULL &&
(*kd)->info.nonleaf.c hild[1] == NULL)
Why is this test necessary? Wouldn't it indicate that there's
a bug somewhere in your tree when this ever should test false?
{
free(*kd);
*kd = NULL;
}
}
}
}
In this program the free_list is a routine to free the link list given
its head pointer and this
is how I wrote it:
void free_list(node *head)
{
node *p;
p = head;
while (p != NULL)
{
free(p);
p = p->next;
}
}
For some reason I observed, the free(p) is not able to execute and the
program terminates at the point without any warning or message. What could
be wrong ?
Not sure if this is the only issue, but here you first free 'p'
and then you dereference it to get at the next pointer. But
using memory you already deallocted is not allowed (even though
you may get away with it often). Store the pointer to the next
element in a temporary variable before you free 'p'.

The other stuff looks ok at a first glance, so I would suspect
that there could be some bug in the code you don't sgow that
creates the linked list.
Regards, Jens
--
\ Jens Thoms Toerring ___ jt@toerring.de
\______________ ____________ http://toerring.de
Jul 6 '08 #2
pereges wrote:
Hi, I'm trying to deallocate a kd tree which I created dynamically.
There were no problems
creating the structure and I can access it easily but there is a
problem while trying to free
it. Here's the structure for the a single node in the tree:
typedef struct kdnode_s
{
bbox box; /* Bounding box */
int splitplane; /* -1 for leaf node*/
union
{
struct
{
struct kdnode_s *child[2]; /* Children node */
double split;

}nonleaf;

struct
{
size_t nt;
node *thead; /* Link list */

}leaf;

}info;

}kdnode;
Some other supporting data structures :

/* vector */

typedef struct
{
double coord[3];

}vector;

/* bounding box */

typedef struct
{
vector maxB, minB;

}bbox;

/* link list node */

typedef struct node_s
{
struct node_s *next;
void *data;

}node;
Heres the function I wrote to free the kdtree. I pass the address of
the root node pointer
and traverse the tree until I reach a leaf node which is characterised
by splitplane member
being -1. If it is not -1, then it has values 0,1,2 and it is a
nonleaf node. The leaf node
is freed and then I try to free other nodes as I climb back. Once a
leaf node is freed its
pointer is made NULL. This makes it easier to free other nodes once
their children have
been freed.

void free_kd_tree(kd node **kd)
{
if (*kd != NULL)
{
if ((*kd)->splitplane == -1)
{
free_list((*kd)->info.leaf.thea d);
*kd = NULL;
return ;
}
else
{
free_kd_tree(&( *kd)->info.nonleaf.c hild[0]);
free_kd_tree(&( *kd)->info.nonleaf.c hild[1]);

if ((*kd)->info.nonleaf.c hild[0] == NULL &&
(*kd)->info.nonleaf.c hild[1] == NULL)
{
free(*kd);
*kd = NULL;
}
}
}
}

In this program the free_list is a routine to free the link list given
its head pointer and this
is how I wrote it:

void free_list(node *head)
{
node *p;

p = head;
while (p != NULL)
{
free(p);
p = p->next;
}
}

For some reason I observed, the free(p) is not able to execute and the
program terminates
at the point without any warning or message. What could be wrong ?
Once p is freed ('free(p);') what do you think 'p->next' means?

--
Joe Wright
"Everything should be made as simple as possible, but not simpler."
--- Albert Einstein ---
Jul 6 '08 #3

"pereges" <Br*****@gmail. comwrote in message
news:29******** *************** ***********@r66 g2000hsg.google groups.com...
Hi, I'm trying to deallocate a kd tree which I created dynamically.
There were no problems
creating the structure and I can access it easily but there is a
problem while trying to free
it. Here's the structure for the a single node in the tree:
[snip]
>
void free_list(node *head)
{
node *p;

p = head;
while (p != NULL)
{
free(p);
Here you free what 'p' points to.
p = p->next;
Here, you try to dereference the pointer just
freed (via the expression 'p->next'). KABOOM.
Undefined behavior.

}
}

For some reason I observed, the free(p) is not able to execute and the
program terminates
at the point without any warning or message. What could be wrong ?
See above.

There may or may not be other problems in your code,
the above is what I noticed right away.

-Mike
Jul 6 '08 #4
On Jul 6, 11:01 pm, j...@toerring.d e (Jens Thoms Toerring) wrote:
if ((*kd)->info.nonleaf.c hild[0] == NULL &&
(*kd)->info.nonleaf.c hild[1] == NULL)

Why is this test necessary? Wouldn't it indicate that there's
a bug somewhere in your tree when this ever should test false?
This test is absolutely necessary because you can detect a leaf node
with its splitplane member being -1. But when both the children of a
non leaf node have been freed, then that non leaf node must also be
freed. It is as good as a leaf node. You can't use the splitplane
criteria to free it because the tree was built in such a way that for
non leaf nodes the split plane value is always 0,1,2 not -1. So what I
do is when I free a leaf node, I make the value of that pointer null :

if ((*kd)->splitplane == -1)
{
free_list((*kd)->info.leaf.thea d);
*kd = NULL;
return ;
}

Once both children of a nonleaf node become null, it fits the
criterion for deletion. Hence the check.
Not sure if this is the only issue, but here you first free 'p'
and then you dereference it to get at the next pointer. But
using memory you already deallocted is not allowed (even though
you may get away with it often). Store the pointer to the next
element in a temporary variable before you free 'p'.

The other stuff looks ok at a first glance, so I would suspect
that there could be some bug in the code you don't sgow that
creates the linked list.
oops, that was probably the problem. I changed it to the following and
it works now :

void free_list(node *head)
{
node *p;

while (head != NULL)
{
p = head->next;
free(head);
head = p;
}
}
Jul 6 '08 #5
Unfotunately, my pelles C compiler never reports such dangerous
situations. Can some one please tell me of some easy to use debugger
in windows mode which will give warnings and stuff ? I know valegrind
is a good one but its for linux. Pelles C has a debugger but it
produces enormous amount of illegible assembly code and various stack
information. I feel extremely frustrated because of these bugs.
Jul 6 '08 #6
pereges wrote:
Unfotunately, my pelles C compiler never reports such dangerous
situations. Can some one please tell me of some easy to use debugger
in windows mode which will give warnings and stuff ? I know valegrind
is a good one but its for linux. Pelles C has a debugger but it
produces enormous amount of illegible assembly code and various stack
information. I feel extremely frustrated because of these bugs.
Have you tried static code checking tools like PC-Lint or splint? They
would've caught the mistake you made.

Jul 7 '08 #7

"santosh" <sa*********@gm ail.comwrote in message
news:g4******** **@registered.m otzarella.org.. .
pereges wrote:
>Unfotunately , my pelles C compiler never reports such dangerous
situations. Can some one please tell me of some easy to use debugger
in windows mode which will give warnings and stuff ? I know valegrind
is a good one but its for linux. Pelles C has a debugger but it
produces enormous amount of illegible assembly code and various stack
information. I feel extremely frustrated because of these bugs.

Have you tried static code checking tools like PC-Lint or splint? They
would've caught the mistake you made.
[original code..]
free(p);
p = p->next;
It's funny but setting p to NULL after the free() may well have helped here,
even though there was an opinion on clc a couple of weeks back that this was
a waste of time.

In fact, the error would then have been so obvious then no lint program or
even compilation would have been necessary:

free(p);
p=NULL;
p = p->next;

On following code, without the root=NULL, 2 compilers produced code that
seemed to work; 2 had code that hung. With root=NULL in place, all crashed
with an error message.

#include <stdio.h>
#include <stdlib.h>

typedef struct {
int data;
void *next;
} node;

int main(void) {
int i;
node *p, *q, *r, *root;

root=NULL;

/* Create linked list */
for (i=1; i<=10; ++i) {
p=malloc(sizeof (node)); /* Assume this works */
p->data=i*100;
p->next=root;
root=p;
}

/* Print it */
p=root;
while (p) {
printf("Item: %d\n",p->data);
p=p->next;
}

/* Free it */
while (root) {
free(root);
// root=NULL;
root=root->next;
}
}

--
Bartc


Jul 7 '08 #8
Bartc wrote:
>
"santosh" <sa*********@gm ail.comwrote in message
news:g4******** **@registered.m otzarella.org.. .
>pereges wrote:
>>Unfotunatel y, my pelles C compiler never reports such dangerous
situations. Can some one please tell me of some easy to use debugger
in windows mode which will give warnings and stuff ? I know
valegrind is a good one but its for linux. Pelles C has a debugger
but it produces enormous amount of illegible assembly code and
various stack information. I feel extremely frustrated because of
these bugs.

Have you tried static code checking tools like PC-Lint or splint?
They would've caught the mistake you made.

[original code..]
> free(p);
p = p->next;

It's funny but setting p to NULL after the free() may well have helped
here, even though there was an opinion on clc a couple of weeks back
that this was a waste of time.

In fact, the error would then have been so obvious then no lint
program or even compilation would have been necessary:

free(p);
p=NULL;
p = p->next;
As was noted earlier, the C standard does not require null pointer
accesses to be caught or diagnosed, though many systems do so. But the
case where all pointers in a program are either valid or NULL is
simpler (if nothing else), than the case where they could, in addition,
have indeterminate values.

Setting pointers to NULL when they have nothing to point at is a good
debugging practise, I agree, but it's no substitute for correct code.

<snip>

Jul 7 '08 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
2358
by: nkrisraj | last post by:
Hi, I have a following structure: typedef struct { RateData rdr; int RateID; char RateBalance; } RateInfo;
0
275
by: nkrisraj | last post by:
Hi, I have a following structure: typedef struct { RateData rdr; int RateID; char RateBalance; } RateInfo;
8
3022
by: nkrisraj | last post by:
Hi, I have a following structure: typedef struct { RateData rdr; int RateID; char RateBalance; } RateInfo;
3
1479
by: uday.das | last post by:
hi , I am not sure but I think it might be to avoid heap fragmentation due to several malloc calls. Are there any strong reason ? What are the other things that should take care when we implement a memory manager , like i) garabage collector kind of thing , ii) Safe Free of pointer in wrapper of Free functions etc . Thanks Uday
0
10357
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
10104
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
8988
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
7510
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6744
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5397
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
4063
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
3668
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2894
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.