Skip to main content
GameDev.net gamedev.net
🔒 Locked

deleting pointers

Started by knyot Jan 12, 2003 at 3:22 PM 29 replies 650+ views
Original Post
knyot
knyot
I have a set up where a node has pointers to 8 children. These children then have children etc, etc. When I clean up, do I need to recurse through each node and delete each pointer or do I just delete the root and its children?
Koen
Koen
If you only delete the root and its children, you''ll have a memory leak: all other nodes will not be deleted.
So: yes, you have to recurse through each node.
Landsknecht
Landsknecht
If you used the new operator to create the link, you would need to recurse the structure and use delete on each link. Frankly, I would just wrap the main structure up as a class with template functions and allow the main class to do the cleanup in the destructor.

God was my co-pilot but we crashed in the mountains and I had to eat him...
My sig used to be, "God was my co-pilot but we crashed in the mountains and I had to eat him..."
But folks whinned and I had to change it.
BitMaster
BitMaster
Depending on you design and what you want to use, you can also delete the pointers to the children in each node''s destructor (strictly speaking this is exactly the recursion already mentioned, but easier to implement than writing it completely by yourself). In this case, you can just delete the root node and all childs will be deleted automatically.
Koen
Koen
quote:
Original post by BitMaster
Depending on you design and what you want to use, you can also delete the pointers to the children in each node''s destructor

This would definitly be the way to go.

Landsknecht
Landsknecht
I like that idea. Kind of a ripple effect. Hadn''t even occured to me, I was stuck in tree recursion mindset.

God was my co-pilot but we crashed in the mountains and I had to eat him...
My sig used to be, "God was my co-pilot but we crashed in the mountains and I had to eat him..."
But folks whinned and I had to change it.
Koen
Koen
Welcome to the magnificent world of OOP ;-)

[edited by - Koen on January 12, 2003 7:19:47 PM]
knyot
knyot
Thank you for the suggestions. I''m going to delete the children through the destructor method. I''m now having a problem deleting the pointer to parent. It is set to NULL at initialization and if I don''t use it, I get errors when I try to delete it. I use an if statement to check if it''s a valid pointer but it still seems to invoke the delete statement when the pointer is NULL. How can i fix this?
Dwiel
Dwiel
I am having a very similar problem and thought that I might just add onto this one instead of posting a new one:

I am writing the template class and am having problems because the template class doesn't know if it is a buffer of other buffers, or of actual data like ints or something. So far I have tried a couple things...

1) I have a function inside my class called del(). I decided I could just call it, but when a problem occurs when I code it... example:.. it's really hard to explain:


        
template <class T> class vector
{
T *ptr; // holds the data

del();
~vector(){del();}
}

template <class T> void vector<T>::del()
{
{
for(int n = 0; n < size; n++)
{
ptr[n].del;
}
}
if(size)
delete [] this->beg(); // beg() gets a T* which points to the first element of the buffer

size = 0;
ptr = 0;
}


the problem with this is that when we get to the final class which has T as an int, we can't call a function from an int... compiler error...

is there a way to inform the compiler to only execute a block a code if T == vector?

[EDIT]
or is there something I could replace "ptr[n].del;" with that would compile when T is an int or a vector?
[/EDIT]

"The only thing worse than not having that new _______ , is when some rich kid has it, but can't and/or doesn't appreciate it."-me
Tazzel3d ~ Dwiel

[edited by - Tazzel3d on January 12, 2003 10:31:16 PM]
Zipster
Zipster
quote:
Original post by knyot
It is set to NULL at initialization and if I don't use it, I get errors when I try to delete it. I use an if statement to check if it's a valid pointer but it still seems to invoke the delete statement when the pointer is NULL. How can i fix this?


Um, just how exactly are you setting up your conditional? It need be only as complicated as this:

if(p)
delete p;


And AFAIK, deleting a NULL pointer has no effect anyway.


@Tazzel3D: Don't try to call a custom function on templated types, it just isn't right. Rely on the deconstructor to do deinitialization. POD's have simple "scalar deconstrutors" IIRC which don't do much, and custom objects should have their own deconstructors that handle their own deinitialization. When you delete the memory, the deconstructors are called automatically.

[edited by - Zipster on January 13, 2003 2:23:26 AM]
Landsknecht
Landsknecht
Calling delete on a NULL pointer is one of those "undefined" behaviors. The result can and will differ from one compiler to another, so ya gotta be a little careful.

My sig used to be, "God was my co-pilot but we crashed in the mountains and I had to eat him..."
But folks whinned and I had to change it.
My sig used to be, "God was my co-pilot but we crashed in the mountains and I had to eat him..."
But folks whinned and I had to change it.
johnnie2
johnnie2
Actually, Zipster''s correct. Deleting a NULL pointer results in very predictable behavior: nothing. Quoted from Marshall Cline''s C++ FAQ Lite,

quote:

[16.7] Do I need to check for NULL before delete p?

No!

The C++ language guarantees that delete p will do nothing if p is equal to NULL.



RapscallionGL - arriving soon.
____________"Optimal decisions, once made, do not need to be changed." - Robert Sedgewick, Algorithms in C
George2
George2
quote:
Original post by knyot
Thank you for the suggestions. I''m going to delete the children through the destructor method. I''m now having a problem deleting the pointer to parent. It is set to NULL at initialization and if I don''t use it, I get errors when I try to delete it. I use an if statement to check if it''s a valid pointer but it still seems to invoke the delete statement when the pointer is NULL. How can i fix this?


You don''t need to delete the pointer to the parent( it will seg fault if you do), because you''re allready deleting the parent.
"THE INFORMATION CONTAINED IN THIS REPORT IS CLASSIFIED; DO NOT GO TO FOX NEWS TO READ OR OBTAIN A COPY." , the pentagon
Dwiel
Dwiel
Let me get this straight... the following code will or will not produce memory leeks:


  
int **tempbuff = new int*[10];
for(int i = 0; i < 10; ++i)
tempbuff[i] = new int[10];
delete [] tempbuff;

//what about:


template <class T> class vector
{
T *ptr;
~vector(){if(ptr) delete [] ptr;};
}

void main(void)
{
vector<vector<int>> vv;
vv.ptr = new int*[10];
for(int i = 0; i < 10; ++i)
vv.ptr[i].ptr = new int[10];
}



so where in the previous code are there memory leaks if any?

Thanx a lot!

"The only thing worse than not having that new _______ , is when some rich kid has it, but can''t and/or doesn''t appreciate it."-me
Tazzel3d ~ Dwiel
doctorsixstring
doctorsixstring
quote:
Original post by johnnie2
Actually, Zipster's correct. Deleting a NULL pointer results in very predictable behavior: nothing. Quoted from Marshall Cline's C++ FAQ Lite,

--------------------------------------
[16.7] Do I need to check for NULL before delete p?

No!

The C++ language guarantees that delete p will do nothing if p is equal to NULL.
--------------------------------------



I use MSVC++ 6.0, and I have caused quite a few crashes due to deleting pointers to objects that do not exist (or that have been previously deleted).

Thus, there are three possibilities:

1) The Marshall Cline FAQ is wrong.
2) The Marshall Cline FAQ is out of date (note the dates: 1991-1996). The standard was not set until 1998.
3) Microsoft Visual C++ is not standard-compliant as pertaining to this feature (which would not be surprising).

-Mike

[edited by - doctorsixstring on January 13, 2003 2:55:21 PM]
johnnie2
johnnie2
quote:
Original post by doctorsixstring
I use MSVC++ 6.0, and I have caused quite a few crashes due to deleting pointers to objects that do not exist (or that have been previously deleted).



Interesting. I pose two questions:

1) Has there ever been a case in which a pointer was explicitly set to NULL (not just that the pointed-to object no longer existed) and the program crashed when attempting to delete the NULLed pointer?

2) Was the previously-deleted object pointer set to NULL before the program attempted to delete it again?

[edited by - johnnie2 on January 13, 2003 3:08:47 PM]
____________"Optimal decisions, once made, do not need to be changed." - Robert Sedgewick, Algorithms in C
necromancer_df
necromancer_df
quote:
Original post by doctorsixstring

I use MSVC++ 6.0, and I have caused quite a few crashes due to deleting pointers to objects that do not exist (or that have been previously deleted).




a pointer to an object that does not exist doesn't necessarily point to null. it will still point to wherever the object was unless you specifically set it to null after deletion. so if you call delete on it you're deleting some random part of memory that may be used for some other object now so when you delete it bad things happen. so pretty much make sure you set pointers to null if you delete what they point to.

edit: seems you beat me to it

[edited by - necromancer_df on January 13, 2003 3:14:59 PM]
Dwiel
Dwiel
I believe that I have confirmed that when using template classes as in the following example, memory can be freed using just one delete [] if proper destors are made:


  
template <class T> class vector
{
public:
T *ptr;

vector()
{
ptr = 0;
}

~vector()
{
if (ptr)
delete [] ptr;
ptr = 0;
}

rsize(int newsize)
{
ptr = new T[newsize];
}
};

typedef vector<int> vectorint;

void main(void)
{
vector<vectorint> vv;
vv.rsize(10);
for(int i = 0; i < 10; ++i)
{
vv.ptr[i].rsize(10);
for(int z = 0; z < 10; ++z)
{
vv.ptr[i].ptr[z] = i * 10 + z;
}
}
vv.~vector();
}


when using just normal pointers to create a 2D array, the memory is not freed with one call. a call to delete [] p as in this following example only deletes the array of pointers to ints... not the actual buffers those pointers point to:


  
int **pp;
pp = new int*[10];
for(int i = 0; i < 10; ++i)
{
pp[i] = new int[10];
for(int z = 0; z < 10; ++z)
{
pp[i][z] = i * 10 + z;
}
}
pp = pp;
delete [] pp;
pp = pp;


hopefully this can be of use to some of you here...

"The only thing worse than not having that new _______ , is when some rich kid has it, but can''t and/or doesn''t appreciate it."-me
Tazzel3d ~ Dwiel

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.