首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

单链表结点反复释放不报错?

2013-01-21 
单链表结点重复释放不报错??本人写了个单链表如下:(MySinglyLinkedList.h)#include iostreamtemplatecl

单链表结点重复释放不报错??
本人写了个单链表如下:(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; //头指针
  LinkedNode<T> *tail; //尾指针
  int length;          //链表长度
};

template<class T>
LinkedList<T>::LinkedList()//链表初始化时为空链表
{
  head = tail = NULL;
  length = 0;
}

template<class T>
LinkedList<T>::~LinkedList()
{
  LinkedNode<T> *ptr = head;
  while (ptr)
  {
    LinkedNode<T> *ptr_del = ptr;
    ptr = ptr->next;
    Delete(ptr_del);
  }
}

template<class T>
void LinkedList<T>::PushNode(T new_data)//链表尾部增加数据为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++;
  }
}

template<class T>
void LinkedList<T>::Delete(LinkedNode<T> *pnode)//删除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()   //输出链表中所有结点
{
  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[])
{
  int list_len = 5;
  srand(time(0));
  if (argc > 1)
    list_len = atoi(argv[1]);

  LinkedList<int> test_list;   //实例化第一个链表 test_list

  for (int i = 0; i < list_len; i++)  //链表长度为输入值list_len,每个元素是随机数
  {
    int cur_data = rand()%list_len;      
    test_list.PushNode(cur_data);
  }
  test_list.Show();
  
  LinkedList<int> test2 = test_list;  //实例化第二个链表 test2
  test2.Show();
 
  return 0;
}



第23行 创建对象test2实际上调用了默认拷贝构造函数,执行位拷贝,所以test2的头指针和尾指针都与test_list相同。那么main函数退出析构test2和test_list时,应该存在重复释放结点空间的问题吧?但为什么本程序运行时没有任何错误呢?

运行环境:Ubuntu 11.04, gcc 4.5.2

谢谢!  linked?list delete 重复释放内存
[解决办法]
LinkedList<int> test2 = test_list;

调用的是赋值构造函数, 楼主你实现的LinkedList类并没有显示实现该方法, 所以程序调用的是自动生成的赋值构造函数, 也就是浅拷贝, 所以不存在重复释放的问题.

另外, 你可以在上面这句下个断点看看里面data的值就知道是不是跟test_list中的data指向同一个地址.
[解决办法]
LinkedList<int> test2 = test_list;
你的这句代码理应调用的是深copy函数,但是在你的类中并没有实现这个函数,所以编译器在需要调用这个函数你却没有提供方的时候,编译器就默认生成一个了,然后调用。这时编译器生成的却是浅复制函数,就是简单的复制变量,不保证指针资源的复制,所以你的test2中的head和tail指针也是指向test_list的链表的头尾的,所以当第一次析构的时候,就把链表资源全部释放掉了,不存在链接了,第二次当然不会去释放了。
[解决办法]
引用:
引用:LinkedList<int> test2 = test_list;
你的这句代码理应调用的是深copy函数,但是在你的类中并没有实现这个函数,所以编译器在需要调用这个函数你却没有提供方的时候,编译器就默认生成一个了,然后调用。这时编译器生成的却是浅复制函数,就是简单的复制变量,不保证指针资源的复制,所以你的test2中的head和ta……

楼主你没有运行崩溃麽。 我这挂了

热点排行