Deleting pointer's pointers - I'm confused

Started by
8 comments, last by papa 19 years, 11 months ago
Hi. Say we have a structure 'tree' containing 2 pointers and a class that uses tree structure to create its member which is a pointer 'Ptr'. Now once I allocate memory for Ptr I know I must delete it in destructor but what avout the internal tree pointers? do I have to delete them first or I shouldnt bother about them and just call single delete to delete 'Ptr' and the internal Ptr's 2 pointers will be deleted automaticaly. consider the code below:


struct tree
{
   int *ptr;
   char *byteData;
}


class Foo
{
   tree *Ptr;  // data member


   Foo()
   {
      Ptr = new tree();
   }
   ~Foo()
   {
      // Which case is correct?

      
      // Case 1. 

      delete Ptr;      // Will it delete also its internal pointers (ptr & byteData)?? 


      // or instead of above I should first call:

      
      // Case 2.

      delete Ptr.ptr;
      delete Ptr.byteData;
      //and then call final delete on 

      delete Ptr;
   }  
}

Thanks. [edited by - papa on May 25, 2004 12:19:33 PM]
Advertisement
no it won''t delete the things they point to.

add a destructor to the the struct to handle deleting the pointers.
Firstly Ptr->(something).

K, when you create a new pointer tree, you create memory for the int* and char*. This should be 4byte+1byte, but on Windows, it might be 4byte+4byte..- err, pointers might always be 4byte. Someone correct me?

So the first time, you create memory for POINTERS. And the second time, you create memory for DATA (or pointers again).

--
You''re Welcome,
Rick Wong
- Google | Google for GameDev.net | GameDev.net''s DirectX FAQ. (not as cool as the Graphics and Theory FAQ)
Case 2 is correct. It would be even better to clean up "tree"''s member pointers in "tree"''s destructor. It is also bad form to make member pointers public. Just an observation.
"When you die, if you get a choice between going to regular heaven or pie heaven, choose pie heaven. It might be a trick, but if it's not, mmmmmmm, boy."
How to Ask Questions the Smart Way.
ok. Thank you.
Yes I completely forgot about the struct's deconstructor.
The struct's destructor will be called before the class's destructor, when I destroy the 'Ptr' using delete Ptr;
ok now I know. But do I really need a contructor for the struct? I guess its safer to always have a contructor/destructor in structs as its members can be initialized to some defauilt values? Am I right? But I've seen most people dont use constructors/deconstructors in their structures. Does it mean they have memory leaks without knowing?

Yes I know the code has all stuff as public but the code is completely meaningless. I just used it for illustration.


[edited by - papa on May 25, 2004 12:33:52 PM]
quote:But do I really need a contructor for the struct?

You don''t *need* one, but it is useful for initializing members.
quote:I guess its safer to always have a contructor/destructor in structs as its members can be initialized to some defauilt values? Am I right?

Right, members can be intialized *and* destroyed by the class they are a member of instead of relying on outside code to do the work.
quote:But I''ve seen most people dont use constructors/deconstructors in their structures. Does it mean they have memory leaks without knowing?

Not neccessarily. You only have a memory leak when you allocate memory and then do not free it up. If the class has no pointers as members, then the members will be cleaned up automagically. If you don''t see destructors or contructors and the struct has pointer members, then the struct is either relying on outside code to do the initialization and cleanup (as per your example), or they are leaking memory.
"When you die, if you get a choice between going to regular heaven or pie heaven, choose pie heaven. It might be a trick, but if it's not, mmmmmmm, boy."
How to Ask Questions the Smart Way.
If you don''t have any functions on the struct and all public data then you rely upon functions outside of the struct looking after the state, keeping it valid, allocating and deallocating the things it points to etc.

This is what encapsulation tries to combat. So:

1) make the data private
2) make functions on the struct to look after any memory issues
3) if you need a destructor you almost certainly need a copy constructor and an assignment operator. Rule of Three: If you have one you need the other two. If you don''t know what they are, look them up.
quote:
Yes I completely forgot about the struct''s deconstructor.
The struct''s destructor will be called before the class''s destructor, when I destroy the ''Ptr'' using delete Ptr;
ok now I know. But do I really need a contructor for the struct? I guess its safer to always have a contructor/destructor in structs as its members can be initialized to some defauilt values? Am I right? But I''ve seen most people dont use constructors/deconstructors in their structures. Does it mean they have memory leaks without knowing?


If the type your creating is a tree, the one you''ve got declared looks more like a tree node, if thats the case the element contained in the node doesn''t have to be a pointers.

It should have members that are pointers to other tree nodes, tree nodes or nodes in general shouldn''t delete itself and the other nodes it points/refers to, thats the job of the main tree type that hides and make it transparent from the user.

If its not some node type then yes if the type claims some resources (like dynamically allocating some memory) from the system then it should be a given back in the deconstructor if not before then.

That might be the reason why you haven''t seen people have deconstructors in ceratin types because its most probably some node type for a some kind of container type there creating.

Also if it is a node type then it doesn''t matter if its members are public because your interface to the main type that is the tree will encapsulate and you can even make it that users never have to deal with nodes directly at all if you make an iterator type to go with it. Here is how i would sort of declare a tree type without a iterator:

template<class T>struct tree_node {tree_node* parent;tree_node* first_child, last_child;tree_node* pred_sib, succ_sib;T element;};template<class T>class tree {public:      typedef tree_node<T>* tree_node_ptr;      typedef unsigned int size_type;       tree();       tree(const tree<T>&);       const tree<T>& operator=(const tree<T>&);       const bool add_child(const T&);       const bool remove_child(const T&);       const is_empty() const;       const size_type size() const;       const bool contains(const T&) const;        void clear();       //tree should be managing deletion of nodes        ~tree() {  clear(); };private:      tree_node_ptr _root;      size_type _size;};
Ok. Now its clear to me!
Thanks all.

Anonymous poster. My code was just invented as I was typing to illustrate my pointer deletion problem. As I mentioned its meaningless. But thank you for your tree explanation.
Its quite neat!
That was me, i made a little mistake but i can''t edit it now doah!. Yeah i know it was an example but i thought that when you where saying that you saw other people''s code having a type with pointers but with no de/constructors i just assumed that you may be looking at a type with self-referenced members that is used to make up some kind of container. In this case the node type shouldn''t do the "resource acquisition is initialization" thing!, tree/tree node was a good example

This topic is closed to new replies.

Advertisement