• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 201
  • Last Modified:

pointers and memory question

Hi,
I am a novice c++ programmer and I am confused about a couple of issues with pointers and memory allocation.   I have three subquestions concerning a class that contains a pointer member variable, but I don't explicitly assign it to a memory location on the free store using new within the class anywhere.  

Part One:
Do I need to worry about deleting it in the destructor?

 For example, here is a Node class that could be used in a linked list.

class Node
{
public:
Node(): next(0) {};
~Node(); // need to delete next here?
private:
Node * next;  // Here is the pointer in question
double its_length;
};

Now imagine I make a pointer to a Node and allocate it some space on the heap with new:

int main()
{
Node * pNode = new Node;  // Line 3
delete pNode;
pNode = 0;
return 0;
}
Part two :
After the use of new in line three, I have pNode point to an object Node allocated on the free store, is the member variable next now on the free store and do I have to worry about delete within the destructor of Node?  This brings up the point that as the author of the class Node but not the main function necesssarily, I don't know whether the Node objects will be placed on the heap or not.  

Part three:
If I don't need to use delete in this simple example, that means the default copy constructor, and assignment operators are also fine?

Thanks for helping me clear up this confusion!
0
kevin_in_va
Asked:
kevin_in_va
1 Solution
 
EarthQuakerCommented:
No, for that case ( linked list ) you shouldn't delete in destructor.

My personal advice is for you to use the standard std::list container, here is a short sample only showing theory :

#include <algorithm>
#include <list>
list<double> lst;
lst.push_back(2.0);
lst.push_back(3.4);
lst.push_back(5.6);
copy(lst.begin(), lst.end(), ostream_iterator<double>(cout));


But if you want to finish your project, you should do it like in C :

class Node
{
public:
Node(): next(0) {};
~Node();
private:
Node * next;
double its_length;
};

int main()
{
  Node* TOP=NULL;

  // creation
  for (int i=0;i<100;i++)
  {
    Node *p = new Node;
    p->next = TOP;
    TOP = p;
  }

  // Use my linked list here


  // deletion
  while (TOP->next)
  {
    delete TOP;
    TOP = TOP->next;
  }

  return 0;
}
0
 
yukapapaCommented:
The member variable next is private, so you can not access the pointer in anywhere outside of the class. Therefore you have to delete the object thru the pointer inside some class member function, ordinarily in the destructor.

If you decide to delete the pointer in the destructor, you have to write appropriate copy constructor and assignment operator or prohivite their use. My preference is allowing copy of the object by reference couting.

Sample code is here, but I think you should use std::list.

class Node{

public:
Node():next(0), refcnt(new int(1)){}
Node(const Node& rhs){Copy();}
Node& operator=(const Node& rhs){Copy(); return *this;}
~Node(){
if(--*refcnt == 0){
delete refcnt;
delete next;
}
Node* GetNextNode()const{return next;}

Node& InsertNextNode(){
Node* tmp = next;
next = new Node;
next->next = tmp;
return *next;
}

private:

void Copy(const Node& rhs){
next = rhs.next;
refcnt = rhs.refcnt;
++*refcnt;
}

Node* next;
int* refcnt;
};

If you don't write appropriate copy constructor or assignment operator, you may delete a object more than once. See below

//Some Node object.
Node node1;

//Copy the object by default copy constructor.
Node node2 = node1;

//Now node1->next and node2->next point to same object.
//The object will be deleted twice by the destructor,
//and the behavior is undefined.
0
 
JoeisanerdCommented:
In your List class you should have a pointer to the beginning of the list. The pointer is of type Node and would be something like Node* Head which would be declared in the private section.  
The following code below is where the Node would be deleted for the linked list. If you were to declare a Node in main then you would use the new and delete operators. You wouldn't call the delete operator in the Node destructor because it is one element and was not created within itself. The list class would be the one creating and deleting nodes for you. The following is an example of how to delete the nodes for linked list. this would be the only place you would need to call delete for the nodes.

~List()
{
 Node* cur;  //Pointer to current node
 Node* nxtNode; //Pointer to the next node
 cur = Head; //your head pointer
 while( cur->next!= NULL )
 {
   nxtNode = cur->next; //keeps track of the next node
   delete cur;  //finally delete the current node
   cur = nxtNode;  //Go to the next node
 }
}

A bit about your question 2. When you use new for an object you are telling the compiler to allocate enough space for all of the variables in the private section of the class, therefore new creates space for a pointer to itself and for the double variable. Delete then returns the space used by those two variables to the heap.

Bottom line, where ever you use new you must use delete once and only once for each new called.

Part 3:
If you didn't use delete in your example above then you would have allocate space that wasn't given up upon exit, therefore memory leak! If you don't use delete then don't use new if you want to let the default stuff happen.

Hope some of this helps.
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Tackle projects and never again get stuck behind a technical roadblock.
Join Now