简体   繁体   中英

C++ Why is Destructor called when I pass a Class Pointer?

int main(){
   //Node is some template class
   Node<int>* head = new Node<int>[5];

   for(int ii = 0; ii < 5; ii++)
   {
      head[ii].set_Data(ii);
      head[ii].set_Link(head + (ii + 1));
      if(ii == 4)
      {
        head[ii].set_Link(NULL);
      }
   }
   delete [] head;
 }


template<typename T>
void Node<T>::set_Link(Node* Node_Address)
{
    Link = Node_Address;
}


template<typename T>
Node<T>::~Node()
{
    delete Link;
    cout << "Destructor" << endl;
}

I'm learning linked lists right now. I don't get why my destructor is called 15 times and cout statement is printed 15 times. If I get rid of the statement

head[ii].set_Link(head + (ii + 1));

The destructor is only called 5 times, which makes sense since 5 classes are made. Why is the destructor called when I use the member function set_Link(), when I am only passing a pointer, not a class. The copy constructor isn't even called. Thanks for any help!

You have UB here. The destructors are called multiple times. delete [] head; calls the destructor of each object in the array. The destructor in turn calls the destructor of the linked object through delete Link; .

In total destructors are called 5 + 4 + 3 + 2 + 1 = 15 times. Mostly on already destroyed objects.

Normally, you wouldn't create an array for the elements of a linked list. Instead, create the list like this:

Node<int>* head = new Node<int>(); 
Node<int>* node = head;
for(int ii = 0; ii < 5; ii++) 
{ 
  node->set_Data(ii); 
  if(ii == 4) 
  { 
    node.set_Link(NULL); 
  }
  else
  {
    Node<int>* next = new Node<int>();
    node->set_Link(next);
    node = next;
  }
} 
delete head; 

In the linked list node destructor you don't want to delete the pointed next node. That will cascade delete all the tail nodes. You could prevent it by setting the pointer to NULL first, but that is just a maintainability nightmare, and it will create a lot of subtle bugs like this.

Note: "Why is the destructor called when I use the member function set_Link()" - It doesn't get called, and it's very easy to verify this by adding a couple of extra trace messages. All destructor calls originate from that one delete [] call.

The full array of five Nodes is created via new, that's ok. But the pointers you pass to set_Link() point to somewhere inside this memory block, so (a) the heap manager doesn't know how to handle them when your destructor calls delete Link; and (b) even if it would know, they get deleted multiple times as your five objects thy to delete each other.

As a note: You only need to delete something you obtained via new .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM