KMemManager.cpp
上传用户:dzyhzl
上传日期:2019-04-29
资源大小:56270k
文件大小:6k
源码类别:

模拟服务器

开发平台:

C/C++

  1. //---------------------------------------------------------------------------
  2. // Sword3 Engine (c) 1999-2000 by Kingsoft
  3. //
  4. // File: KMemManager.cpp
  5. // Date: 2000.08.08
  6. // Code: WangWei(Daphnis)
  7. // Desc: Memory Opration Class Using Heap Memory Functions
  8. //---------------------------------------------------------------------------
  9. #include "KWin32.h"
  10. #include "KDebug.h"
  11. #include "KMemBase.h"
  12. #include "KMemManager.h"
  13. //---------------------------------------------------------------------------
  14. ENGINE_API KMemManager g_MemManager;
  15. //---------------------------------------------------------------------------
  16. // 函数: KMemManager
  17. // 功能: 购造函数
  18. // 参数: void
  19. // 返回: void
  20. //---------------------------------------------------------------------------
  21. KMemManager::KMemManager()
  22. {
  23.     int i;
  24.     for (i = 0; i<NUM_BLOCK; i++)
  25.         m_block_size[i] = (1<<(i + MIN_BLOCK)); //块的大小
  26. g_MemZero(m_blocks, sizeof(m_blocks));
  27. }
  28. //---------------------------------------------------------------------------
  29. // 函数: ~KMemManager
  30. // 功能: 析购函数
  31. // 参数: void
  32. // 返回: void
  33. //---------------------------------------------------------------------------
  34. KMemManager::~KMemManager()
  35. {
  36.     KChunkHeader* ch;
  37. KBlockHeader* bh;
  38. char* bp;
  39. int i;
  40. // 检测内存泄漏
  41.     while (ch = (KChunkHeader *)m_chunks.GetHead())
  42. {
  43.         bp = ((char *)ch) + sizeof(KChunkHeader);
  44.         for (i = 0; i < ch->block_num; i++)
  45. {
  46.             bh = (KBlockHeader *)bp;
  47.             if (bh->size != 0)// 有没释放的内存块?
  48. g_DebugLog("KMemManager::Leak Detected, Size = %d", bh->size);
  49. bp += ch->block_size;
  50.         }
  51.         FreeChunk(ch);
  52.     }
  53. }
  54. //---------------------------------------------------------------------------
  55. // 函数: NewChunk()
  56. // 功能: 创建新的内存分配块,CHUNK_SIZE为单位
  57. // 参数: block size, block number
  58. // 返回: block header
  59. //---------------------------------------------------------------------------
  60. void* KMemManager::NewChunk(int block_size, int block_num)
  61. {
  62. // 块的大小要加上块头和块尾
  63.     block_size = block_size + sizeof(KBlockHeader) + sizeof(KBlockTailer);
  64. // chunk的大小要包括chunk header
  65.     int chunk_size = sizeof(KChunkHeader) + (block_size * block_num);
  66.     // 分配一大块内存
  67. char* c = (char*)g_MemAlloc(chunk_size);
  68.     if (c)
  69. {
  70.         // ChunkHeader initialization
  71.         KChunkHeader* ch = (KChunkHeader *)c;
  72. ch->node.m_pNext = NULL;
  73. ch->node.m_pPrev = NULL;
  74.         ch->block_num  = block_num;
  75.         ch->block_size = block_size;
  76.         m_chunks.AddTail((KNode *)ch);
  77.         // blocks im Chunk initializtion
  78.         char *f = c + sizeof(KChunkHeader); // first Block
  79.         char *p = c + chunk_size; // last Block + 1
  80.         char *next = NULL;
  81.         while (p > f)
  82. {
  83.             p -= block_size;
  84.             KBlockHeader *bh = (KBlockHeader *)p;
  85.             bh->next = (void *)next;
  86.             bh->size = 0;
  87.             bh->magic = HEAD_MAGIC;
  88.             next = p;
  89.         }
  90.         return f;
  91.     }
  92.     return NULL;
  93. }
  94. //---------------------------------------------------------------------------
  95. // 函数: FreeChunk()
  96. // 功能: 创建新的内存分配块,CHUNK_SIZE为单位
  97. // 参数: block size, block number,
  98. // 返回: block header
  99. //---------------------------------------------------------------------------
  100. void KMemManager::FreeChunk(KChunkHeader *ch)
  101. {
  102. ch->node.Remove();
  103. g_MemFree((void *)ch);
  104. }
  105. //---------------------------------------------------------------------------
  106. // 函数: Malloc()
  107. // 功能: 分配内存
  108. // 参数: size in bytes
  109. // 返回: void*
  110. //---------------------------------------------------------------------------
  111. void* KMemManager::Malloc(int size)
  112. {
  113.     char* p = NULL;
  114.     
  115. if (size > (1<<MAX_BLOCK))
  116. {
  117.         p = (char *)NewChunk(size, 1);
  118.         if (p)
  119. {
  120.             KBlockHeader *bh = (KBlockHeader *)p;
  121.             KBlockTailer *bp = (KBlockTailer *)(p + size + sizeof(KBlockHeader));
  122.             bh->next = (void *) -1L;// 表示只有一块
  123.             bh->size = size;
  124.             bh->magic = HEAD_MAGIC;
  125.             bp->magic = TAIL_MAGIC;
  126.             p += sizeof(KBlockHeader);
  127.         }
  128.     }
  129. else
  130. {
  131.         // 找一个大小合适的chunk
  132.         int i, mask;
  133.         for (i=0; i<NUM_BLOCK-1; i++)
  134. {
  135.             mask = ~(m_block_size[i]-1);
  136.             if ((size & mask) == 0)
  137.                 break;
  138.         }
  139.         if (NULL == m_blocks[i])
  140. {
  141. m_blocks[i] = NewChunk(m_block_size[i], 
  142. CHUNK_SIZE / m_block_size[i]);
  143. }
  144.         p = (char *)m_blocks[i];
  145. KBlockHeader *bh = (KBlockHeader *)p;
  146. KBlockTailer *bp = (KBlockTailer *)(p + size + sizeof(KBlockHeader));
  147. m_blocks[i] = bh->next;
  148. bh->next = (void *)i;
  149. bh->size = size;
  150. bh->magic = HEAD_MAGIC;
  151. bp->magic = TAIL_MAGIC;
  152. p += sizeof(KBlockHeader);
  153.     }
  154.     return p;
  155. }
  156. //---------------------------------------------------------------------------
  157. // 函数: Calloc()
  158. // 功能: 分配内存,并用零填充
  159. // 参数: size in bytes
  160. // 返回: void*
  161. //---------------------------------------------------------------------------
  162. void* KMemManager::Calloc(int size)
  163. {
  164. void* p = Malloc(size);
  165. g_MemZero(p, size);
  166. return p;
  167. }
  168. //---------------------------------------------------------------------------
  169. // 函数: Free()
  170. // 功能: 释放内存
  171. // 参数: void*
  172. // 返回: void
  173. //---------------------------------------------------------------------------
  174. void KMemManager::Free(void* p)
  175. {
  176. if (NULL == p)
  177. {
  178. g_DebugLog("KMemManager::Free(p); p = NULL!");
  179. return;
  180. }
  181.     char* pc = (char *)p;
  182.     KBlockHeader *bh = (KBlockHeader *)(pc - sizeof(KBlockHeader));
  183.     KBlockTailer *bp = (KBlockTailer *)(pc + bh->size);
  184.     // 检测是否存在内存越界访问
  185.     if ((bh->magic != HEAD_MAGIC) || (bp->magic != TAIL_MAGIC))
  186.         g_MessageBox("Memory Corrupted : Size = %d", bh->size);
  187. // 单独分配的内存块
  188.     if (((int)bh->next) == -1L)
  189. {
  190.         KChunkHeader *ch = (KChunkHeader *)(((char *)bh) - sizeof(KChunkHeader));
  191.         bh->size = 0;
  192.         FreeChunk(ch);
  193.     }
  194. else
  195. {
  196.         int i = (int)bh->next;
  197.         KBlockHeader* next = (KBlockHeader *)m_blocks[i];
  198.         m_blocks[i] = bh;
  199.         bh->next = next;
  200.         bh->size = 0;
  201.     }
  202. }
  203. //---------------------------------------------------------------------------