zoukankan      html  css  js  c++  java
  • 重复造轮子系列--内存池(C语言)

    这个代码是我上个公司工作项目的里面内存管理(基于伙伴算法)的一个简化又简化的版本。

    因为没有内存边界检查;

    因为没有内存使用统计;

    因为没有考虑线程安全;

    因为没有内存分配操作的具体文件位置信息;

    因为没有考虑内存的浪费;

    因为特别简单。。。所以也有一些用处,我定义了最小的内存为8字节,因此可以将任意内存大小散列到8的倍数之内,对于64位的通信系统来说,字节对齐是非常重要的;

    mem_pool.h

     1 #ifndef MEM_POOL_H_
     2 #define MEM_POOL_H_
     3 
     4 typedef struct MemBlock {
     5     struct MemBlock* next;
     6     int size;
     7     void *ptr;
     8 } MemBlock;
     9 
    10 typedef unsigned char byte;
    11 
    12 // 8 16 32 64 128 256 512 1024 2048 4096 
    13 // 1 2  4  8  16  32  64  128  256  512
    14 // 0 1  2  3  4   5   6   7    8    9
    15 
    16 #define MEM_POOL_MAX 10
    17 #define MEM_BLOCK 8
    18 #define MEM_BLOCK_BASE 8192
    19 #define MEM_BLOCK_TYPE_NUM 10
    20 #define MEM_BLOCK_FREE -1
    21 
    22 int       mem_pool_index(size_t size);
    23 void      mem_pool_init();
    24 void      mem_pool_free();
    25 int       mem_block_num(size_t size);
    26 MemBlock* mem_block_head_get(size_t size);
    27 void*     mem_get(size_t size);
    28 int       mem_free(void **ptr);
    29 
    30 #define mem_ret(ptr) mem_free((void **)&ptr)
    31 
    32 //////////////////////////////////////////////////////////////////////////
    33 
    34 typedef struct MemBlockDlist {
    35     struct MemBlockDlist* prev;
    36     struct MemBlockDlist* next;
    37     int size;
    38     void *ptr;
    39 } MemBlockDlist;
    40 
    41 void  mem_pool_dlist_init();
    42 void  mem_pool_dlist_free();
    43 void* mem_realloc(size_t size);
    44 void  mem_release(void** ptr);
    45 
    46 #define mem_alloc(s) mem_realloc(s)
    47 #define mem_relex(p) mem_release((void **)&p)
    48 
    49 #endif

    mem_pool.c

      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 #include <math.h>
      4 #include "mem_pool.h"
      5 
      6 static byte*     g_pool_mem[MEM_POOL_MAX] = {0};
      7 static MemBlock* g_pool[MEM_POOL_MAX]     = {0};
      8 const float log2 = log(2.0);
      9 int mem_pool_index(size_t size) {
     10     if (size > 0 && size <= MEM_BLOCK) return 0;
     11 
     12     size_t s = 1;
     13     size_t t = size;
     14     size_t i;
     15 
     16     i = log((float)t)/log2; 
    17
    s = s<<i; 18 return s == size ? i-3 : i-2; 19 } 20 21 MemBlock* mem_block_head(size_t index) { 22 if (index < 0 || index >= MEM_POOL_MAX) 23 return NULL; 24 25 return g_pool[index]; 26 } 27 28 MemBlock* mem_block_head_get(size_t size) { 29 if (size > MEM_BLOCK_BASE/2 || size <= 0) { 30 printf("size=%d too big to mem pool. using malloc plz ", size); 31 return NULL; 32 } 33 return mem_block_head(mem_pool_index(size)); 34 } 35 36 int mem_block_num(size_t size) { 37 return MEM_BLOCK_BASE/size;// size > 0 is true 38 } 39 40 static MemBlock* mem_block_alloc(byte* buf, int block_size, int block_num) { 41 MemBlock *head, *curr, *next; 42 int i; 43 44 head = (MemBlock *)buf; 45 head->size = MEM_BLOCK_FREE; 46 head->ptr = (byte*)head + sizeof(MemBlock); 47 head->next = NULL; 48 49 curr = head; 50 for (i=1; i<block_num; i++) { 51 next = (MemBlock*)((byte*)curr + block_size); 52 next->size = MEM_BLOCK_FREE; 53 next->ptr = (byte*)next + sizeof(MemBlock); 54 curr->next = next; 55 next->next = NULL; 56 curr = next; 57 } 58 return head; 59 } 60 61 void mem_pool_init() { 62 size_t l, i, s, n, b; 63 for (l=0; l<MEM_BLOCK_TYPE_NUM; l++) { 64 i = 1 << l; 65 b = i * MEM_BLOCK; 66 s = b + sizeof(MemBlock); 67 n = mem_block_num(b); 68 69 g_pool_mem[l] = (byte *)malloc(s * n); 70 if (NULL == g_pool_mem[l]) { 71 break; 72 } 73 g_pool[l] = mem_block_alloc(g_pool_mem[l], s, n); 74 } 75 return; 76 } 77 78 void mem_pool_free() { 79 for (int i=0; i<MEM_BLOCK_TYPE_NUM; i++) { 80 if (NULL != g_pool_mem[i]) { 81 free(g_pool_mem[i]); 82 g_pool_mem[i] = NULL; 83 g_pool[i] = NULL; 84 } 85 } 86 return; 87 } 88 89 void* mem_get(size_t size) { 90 MemBlock* head = mem_block_head_get(size); 91 if (NULL == head) return NULL; 92 93 do { 94 if (head->size == MEM_BLOCK_FREE) { 95 head->size = size; 96 return head->ptr; 97 } else { 98 head = head->next; 99 } 100 } while (head->next); 101 102 return NULL; 103 } 104 105 int mem_free(void **ptr) { 106 if (NULL == ptr || NULL == *ptr) return 0; 107 108 MemBlock *block = (MemBlock *)((byte*)(*ptr) - sizeof(MemBlock)); 109 block->size = MEM_BLOCK_FREE; 110 111 return 1; 112 }

    mem_pool_dlist.c

      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 #include <string.h>
      4 #include <math.h>
      5 #include "mem_pool.h"
      6 
      7 static byte*          g_pool_buff[MEM_POOL_MAX]     = {0};
      8 static MemBlockDlist* g_pool_objects[MEM_POOL_MAX]  = {0};
      9 static MemBlockDlist* g_pool_freelist[MEM_POOL_MAX] = {0};
     10 static MemBlockDlist* g_pool_cursor[MEM_POOL_MAX]   = {0};
     11 
     12 MemBlockDlist* mem_block_dlist_head(size_t index) {
     13     if (index < 0 || index >= MEM_POOL_MAX) 
     14         return NULL;
     15 
     16     return g_pool_objects[index];
     17 }
     18 
     19 void mem_pool_cursor_init() {
     20     for(size_t i=0; i<MEM_POOL_MAX; i++)
     21         g_pool_cursor[i] = mem_block_dlist_head(i);
     22 }
     23 
     24 static MemBlockDlist* mem_block_dlist_alloc(byte* buf, int bk_size, int bk_num){
     25     MemBlockDlist *head, *curr, *next;
     26     int i;
     27 
     28     head = (MemBlockDlist *)buf;
     29     head->size = MEM_BLOCK_FREE;
     30     head->ptr  = (byte*)head + sizeof(MemBlockDlist);
     31     head->prev = NULL;
     32     head->next = NULL;
     33 
     34     curr = head;
     35     for (i=1; i<bk_num; i++) {
     36         next = (MemBlockDlist*)((byte*)curr + bk_size);
     37         next->size = MEM_BLOCK_FREE;
     38         next->ptr  = (byte*)next + sizeof(MemBlockDlist);
     39 
     40         curr->next = next;
     41         next->prev = curr;
     42         next->next = NULL;
     43 
     44         curr = next;
     45     }
     46     return head;
     47 }
     48 
     49 void mem_pool_dlist_init() {
     50     size_t l, i, s, n, b;
     51     for (l=0; l<MEM_BLOCK_TYPE_NUM; l++) {
     52         i = 1 << l;
     53         b = i * MEM_BLOCK;
     54         s = b + sizeof(MemBlockDlist);
     55         n = mem_block_num(b);
     56 
     57         g_pool_buff[l] = (byte *)malloc(s * n);
     58         if (NULL == g_pool_buff[l]) {
     59             break;
     60         }
     61         g_pool_objects[l] = mem_block_dlist_alloc(g_pool_buff[l], s, n);
     62     }
     63 
     64     mem_pool_cursor_init();
     65 }
     66 
     67 void mem_pool_dlist_free() {
     68     for (int i=0; i<MEM_BLOCK_TYPE_NUM; i++) {
     69         if (NULL != g_pool_buff[i]) {
     70             free(g_pool_buff[i]);
     71 
     72             g_pool_buff[i]     = NULL;
     73             g_pool_objects[i]  = NULL;
     74             g_pool_freelist[i] = NULL;
     75             g_pool_cursor[i]   = NULL;
     76         }
     77     }
     78 }
     79 
     80 MemBlockDlist* mem_free_block_get(int index) {
     81     if (index < 0 || index >= MEM_POOL_MAX) return NULL;
     82 
     83     MemBlockDlist* tmp = g_pool_freelist[index];
     84     if (!tmp) return NULL;
     85 
     86     g_pool_freelist[index] = tmp->next;
     87     g_pool_freelist[index]->prev = NULL;
     88     tmp->next = NULL;
     89 
     90     return tmp;
     91 }
     92 
     93 void* mem_realloc(size_t size) {
     94     int index = mem_pool_index(size);
     95     if (index < 0 || index >= MEM_POOL_MAX) 
     96         return NULL;
     97     
     98     MemBlockDlist* ptr = mem_free_block_get(index);
     99     if (ptr) {
    100         ptr->size = size;
    101         return ptr->ptr;
    102     }
    103 
    104     MemBlockDlist* cursor = g_pool_cursor[index];
    105     if (NULL == cursor) {
    106         printf("pool index=%d memory leak or queue is all used.
    ", index);
    107         return NULL;
    108     }
    109     
    110     if (MEM_BLOCK_FREE == cursor->size) {
    111         g_pool_cursor[index] = cursor->next;
    112         cursor->size = size;
    113         return cursor->ptr;
    114     }
    115 
    116     return NULL;
    117 }
    118 
    119 void  mem_release(void** ptr) {
    120     if (NULL == ptr || NULL == *ptr) 
    121         return;
    122 
    123     size_t len = sizeof(MemBlockDlist);
    124     MemBlockDlist *block = (MemBlockDlist *)((byte*)(*ptr) - len);
    125 
    126     int index = mem_pool_index(block->size);
    127     if (index < 0 || index >= MEM_POOL_MAX) 
    128         return;
    129 
    130     memset((byte*)(*ptr), 0, block->size);
    131     MemBlockDlist* top = g_pool_freelist[index];
    132 
    133     g_pool_freelist[index] = block;
    134     if (top) {    
    135         g_pool_freelist[index]->next = top;
    136     }
    137 
    138     g_pool_freelist[index]->size = MEM_BLOCK_FREE;
    139 }
  • 相关阅读:
    用OpenGL简单编写的一个最简单贪吃蛇游戏
    Python lambda map filter reduce
    Hadoop Python MapReduce
    Python faker生成数据
    Pandas数据清洗
    PySpark与jupyer notebook
    虚拟机与宿主机网络共享
    集合覆盖问题与贪婪算法
    最快路径与狄克斯特拉
    最短路径问题与广度优先搜索
  • 原文地址:https://www.cnblogs.com/danxi/p/6370012.html
Copyright © 2011-2022 走看看