鱼C论坛

 找回密码
 立即注册
查看: 3761|回复: 7

[技术交流] 来,大家看一个单链表~ 推荐,因为内存分配方式很独特哦~

[复制链接]
发表于 2014-2-24 23:29:08 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 andalousie 于 2014-4-11 16:10 编辑

List.h
  1. #if !defined (LIST_H)
  2. #define LIST_H
  3. #include <new>

  4. class LinkAllocator;

  5. class List
  6. {
  7. public:
  8.         List ();
  9.         ~List ();
  10.         void insert (int value);
  11.         bool isEmpty() const { return !_pHead; } // conversion to bool
  12. public:
  13.         class Link
  14.         {
  15.         public:
  16.                 Link (Link* pNext, int value = -1)
  17.                         : _pNext (pNext), _value (value) {}
  18.                 Link *  Next () const { return _pNext; }
  19.                 void        SetNext (Link * next) { _pNext = next; }
  20.                 int     GetValue () const { return _value; }
  21.                 // allocator
  22.                 void * operator new (std::size_t size);
  23.                 void   operator delete (void * mem);
  24.                 static void Purge (); //Purge method is used to release the memory
  25.         private:
  26.                 static LinkAllocator _linkAlloc;
  27.                
  28.                 Link *  _pNext;
  29.                 int                _value;
  30.         };
  31. public:
  32.         class iterator
  33.         {
  34.         public:
  35.                 void      operator =  (const iterator& it) { _pLink = it._pLink; }
  36.                 bool      operator == (const iterator& it) { return _pLink == it._pLink; }
  37.                 bool      operator != (const iterator& it) { return _pLink != it._pLink; }
  38.                 iterator& operator ++ () { _pLink = _pLink->Next (); return *this; }
  39.                 int       operator *  () const { return _pLink->GetValue (); }
  40.                
  41.                 iterator  operator + (std::size_t n)
  42.                 {
  43.                         iterator tmp = *this;
  44.                         while(n--) ++tmp;
  45.                         return tmp;
  46.                 }

  47.                 iterator (Link const * p = 0)
  48.                         : _pLink (p) {}
  49.                 iterator (const iterator& it)
  50.                         : _pLink (it._pLink) {}
  51.         private:
  52.                 Link const * _pLink; // current link
  53.         };

  54.         friend class iterator;
  55.         iterator begin () { return iterator (_pHead); }
  56.         iterator end   () { return iterator (0); }
  57. private:
  58.         Link const * GetHead () const { return _pHead; }
  59.         
  60.         Link * _pHead;
  61. };

  62. class LinkAllocator
  63. {
  64.         enum { BlockLinks = 4 }; // small value for testing
  65.         class Block
  66.         {
  67.         public:
  68.                 Block (Block * next): _next (next) {}
  69.                 Block * Next () { return _next; }
  70.         private:
  71.                 Block * _next;
  72.         };
  73. public:
  74.         LinkAllocator () : _p (0), _blocks (0) {}
  75.         ~LinkAllocator () { Purge (); }
  76.         void Purge ();
  77.         void * NewLink ();
  78.         void Recycle (void * link);
  79. private:
  80.         List::Link  * _p;
  81.         Block * _blocks;
  82. };

  83. #endif
复制代码
list.cc
  1. #include "List.h"
  2. #include <cassert>
  3. #include <iostream>

  4. LinkAllocator List::Link::_linkAlloc;

  5. void * List::Link::operator new (std::size_t size)
  6. {
  7.         assert (size == sizeof (Link));
  8.         return _linkAlloc.NewLink ();
  9. }

  10. void List::Link::operator delete (void * mem)
  11. {
  12.         if (mem)
  13.                 _linkAlloc.Recycle (mem);
  14. }

  15. void List::Link::Purge () { _linkAlloc.Purge (); }

  16. // List

  17. List::List ()
  18.         : _pHead (0)
  19. {}

  20. List::~List ()
  21. {
  22.         while ( _pHead != 0 )
  23.         {
  24.                 Link * pLink = _pHead;
  25.                 _pHead = _pHead->Next (); // unlink pLink
  26.                 delete pLink;
  27.         }
  28. }

  29. void List::insert (int value)
  30. {
  31.         Link * pLink = new Link (_pHead, value);
  32.         _pHead = pLink;
  33. }

  34. // LinkAllocator

  35. void * LinkAllocator::NewLink ()
  36. {
  37.         if (_p == 0)
  38.         {
  39.                 std::cout << "\tAllocating a new block\n";
  40.                 // use global operator new to allocate a block of links
  41.                 char * p = ::new char [sizeof (Block) + BlockLinks * sizeof (List::Link)];
  42.                 // add it to the list of blocks
  43.                 Block * block = ::new (p) Block (_blocks);
  44.                 _blocks = block;
  45.                 // add it to the list of links
  46.                 p += sizeof (Block);
  47.                 for (int i = 0; i < BlockLinks; ++i)
  48.                 {
  49.                         List::Link * link = ::new (p) List::Link (_p);
  50.                         _p = link;
  51.                         p += sizeof (List::Link);
  52.                 }
  53.         }
  54.         void * mem = _p;
  55.         _p = _p->Next ();
  56.         std::cout << "\tGetting link from free list\n";
  57.         return mem;
  58. }

  59. void LinkAllocator::Recycle (void * mem)
  60. {
  61.         std::cout << "\tReturning link to free list\n";
  62.         List::Link * link = static_cast<List::Link *> (mem);
  63.         link->SetNext (_p);
  64.         _p = link;
  65. }

  66. void LinkAllocator::Purge ()
  67. {
  68.         std::cout << "\tPurging link allocator\n";
  69.         while (_blocks != 0)
  70.         {
  71.                 // it was allocated as an array of char
  72.                 char * mem = reinterpret_cast<char *> (_blocks);
  73.                 _blocks = _blocks->Next();
  74.                 ::delete [] mem;
  75.         }
  76. }
复制代码
测试文件testlist.cpp
  1. #include <iostream>
  2. #include "List.h"

  3. int main()
  4. {
  5.         List list;
  6.         list.insert (1);
  7.         list.insert (2);
  8.         list.insert (5);
  9.         list.insert (3);
  10.         std::cout << "List contents:\n";
  11.         for (List::iterator it = list.begin();
  12.              it != list.begin() + 2;
  13.              ++it)
  14.         {
  15.                 std::cout << *it << " ";
  16.         }
  17.         std::cout << std::endl;
  18. }
复制代码
输出结果
snap.jpg

可以看出链表的allocator通过整体性的Block分配内存,然后切割分给Link使用。用完后先由allocator的Recycle方法回收,最后由析构函数统一调用Purge方法释放。增加了效率。
链表的iterator本人只写出了正向的,因为是单链表;如果是像标准库里面一样,双向链表,就可以用prev指针来实现逆向迭代了。讲述到此完毕,请支持!!
其中空间配置器参考了http://www.drdobbs.com/a-quick-and-simple-memory-allocator/184403440
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2014-2-25 08:21:19 | 显示全部楼层
好的,谢谢楼主,我先收藏了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-4-11 03:22:09 | 显示全部楼层
没有注释 看的头大
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-4-11 15:58:48 | 显示全部楼层
本帖最后由 andalousie 于 2014-4-11 16:13 编辑

没事,亲,这就注释一下~。不过具体点,请问你需要注释哪儿呢?除了我注释过的,虽然是英文哈~ 我不习惯用中文注释程序。中文解释一般放在程序外面。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-4-12 14:42:25 | 显示全部楼层
andalousie 发表于 2014-4-11 15:58
没事,亲,这就注释一下~。不过具体点,请问你需要注释哪儿呢?除了我注释过的,虽然是英文哈~ 我不习惯用 ...

没想到楼主会回复哈 其实注释倒不用多详细 只需在方法前和类前面注释就行了 比如说 这个方法是干什么的 这个字段声明是干嘛的等等
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-4-12 21:48:48 | 显示全部楼层
Fly_Sheep 发表于 2014-4-12 14:42
没想到楼主会回复哈 其实注释倒不用多详细 只需在方法前和类前面注释就行了 比如说 这个方法是干什么的 这 ...

那我简单列述一下吧
ListAllocator类
  1. class Block 用于划分内存块
  2. Newlink申请新的空间给链结构
  3. Purge释放
  4. Recycle回收
复制代码
List类
  1. List() 构造函数
  2. ~List() 析构函数
  3. List::Link 嵌入的类Link声明
  4. List::iterator类 迭代器,就是重载各种运算符的类,表现出来就像指针
复制代码
这是主要方法的中文名称
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-4-18 19:22:07 | 显示全部楼层
这个必须要看看那啊
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-8-12 08:14:07 | 显示全部楼层
谢谢楼主分享!!!!!!!!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-5-11 14:58

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表