为什么当我删除两次相同的内存时没有错误?

Why there's no error when I delete twice the same memory?

本文关键字:内存 有错误 两次 删除 为什么      更新时间:2023-10-16

MySinglyLinkedList.h:

#include <iostream>
template<class T> class LinkedList;
template<class T>
class LinkedNode {   
 public:
  LinkedNode(T new_data):data(new_data) {; }
 private:
  friend class LinkedList<T>; 
  LinkedNode<T> *next;
  T data;
};
template<class T>
class LinkedList {   
 public:
  LinkedList();
  ~LinkedList();
  void PushNode(T new_data);
  void Delete(LinkedNode<T> *pnode);
  void Show();
 private:
  LinkedNode<T> *head; //Head pointer
  LinkedNode<T> *tail; //Tail pointer
  int length;          //Length of the list
};
//Initialize an empty list when creating it
template<class T>
LinkedList<T>::LinkedList()
{
  head = tail = NULL;
  length = 0;
}
//delete all the nodes when deconstructing the object
template<class T>
LinkedList<T>::~LinkedList()
{
  LinkedNode<T> *ptr = head;
  while (ptr)
  {
    LinkedNode<T> *ptr_del = ptr;
    ptr = ptr->next;
    Delete(ptr_del);
  }
}
//Add one node to the tail of the list
template<class T>
void LinkedList<T>::PushNode(T new_data)
{
  LinkedNode<T> *pnew_node = new LinkedNode<T>(new_data);
  pnew_node->next = NULL;
  if (!length) {
    head = tail = pnew_node;
    length++;
  } else {
    tail->next = pnew_node;
    tail = pnew_node;
    length++;
  }
}
//Delete the node pointed by pnode
template<class T>
void LinkedList<T>::Delete(LinkedNode<T> *pnode)
{
  LinkedNode<T> *ptr = head;
  if (pnode==head) {
    head = pnode->next;
  } else {
    while(ptr->next != pnode)
    {
      ptr = ptr->next;
    }    
    ptr->next = pnode->next;
  }
  if(pnode == tail)
     tail = ptr;
  delete pnode;
  length--;
}
template<class T>
void LinkedList<T>::Show()   //Print all the contents in the list
{
  LinkedNode<T> *pnode = head;
  while(pnode)
  {
    std::cout << pnode->data << std::endl;
    pnode = pnode->next;
  }
  std::cout << "In total: " << length << std::endl;  
}

主要功能如下:

#include "MySinglyLinkedList.h"
#include <cstdlib>
#include <ctime>
using namespace std;
int main(int argc, char *argv[])
{
  //list_len is the length of the list
  int list_len = 5;
  srand(time(0));
  if (argc > 1)
    list_len = atoi(argv[1]);
  LinkedList<int> test_list;   //Create the first list: test_list
  for (int i = 0; i < list_len; i++)
  {
    //The elements in the list are random integers
    int cur_data = rand()%list_len;      
    test_list.PushNode(cur_data);
  }
  test_list.Show();
  LinkedList<int> test2 = test_list;  //Create the second list: test2
  test2.Show();
  return 0;
}

由于我在这里没有定义任何复制构造函数,因此在创建第二个列表时,将调用默认的复制构造函数并执行位复制,因此test_listtest2将指向同一个链表。因此,当两个对象被解构时,列表的第一个节点将被删除两次。但事实上,当我使用GCC编译程序时,并没有发生任何错误,它在Linux中成功运行我不明白为什么没有发生错误

删除已删除的指针会导致未定义的行为,因此任何事情都可能发生。如果您想确保没有发生任何事情,请在删除后将指针设置为null。删除null没有任何作用,也不会导致错误。

请参阅:c++delete(wikipedia(

根据Diego的回答,C++标准允许删除NULL指针。编译器无法知道第二次删除指针时指针将包含什么值(即它可能为NULL(,因此它别无选择,只能允许它符合标准。