亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C > 正文

基于一個簡單定長內存池的實現方法詳解

2020-01-26 16:16:46
字體:
來源:轉載
供稿:網友

    主要分為 3 個部分,memoryPool 是管理內存池類,block 表示內存塊,chunk 表示每個存儲小塊。它們之間的關系為,memoryPool 中有一個指針指向某一起始 block,block 之前通過 next 指針構成鏈表結構的連接,每個 block 包含指定數量的 chunk。每次分配內存的時候,分配 chunk 中的數據地址。

內存池設計文檔

主要數據結構設計:

Block:

復制代碼 代碼如下:

struct block {
    block * next;//指向下一個block指針
    unsigned int numofChunks;
    unsigned int numofFreeChunks;//剩余free的chunk數量
    unsigned int blockNum;//該block的編號
    char * data;
    queue<int> freepos; //記錄可用chunk序號
};

MemoryPool:
復制代碼 代碼如下:

class memoryPool {
    unsigned int initNumofChunks; //每個block的chunk數量
    unsigned int chunkSize;//每個chunk的數據大小
    unsigned int steps;//每次擴展的chunk數量
    unsigned int numofBlocks;//當前管理多少個blocks
    block * blocksPtr;//指向起始block
    block * blocksPtrTail;//指向末尾block
    block * firstHasFreeChunksBlock;//指向第一個不為空的block
};

Chunk:

ChunkNum:該 chunk 所在 block 里的編號

blockAddress: 該 chunk 所對應的 block,主要用于 free 這個 chunk 的時候,能夠快速找到所屬 block,并進行相應更新

data:實際供使用的數據起始位置

關鍵操作說明:

內存分配:

從 firstHasFreeChunksBlock 開始查找第一個有 free 位置的 block,如果找到,則則獲取該 block 的 freepos 的隊首元素,返回該元素序號對應的 chunk 的數據地址,并將 freepos 的隊首元素彈出,其他相關屬性更新。如果找不到,則新增 steps 個 chunk,再重復上面的過程。

內存釋放:

傳入待釋放的地址指針p,通過對p的地址移動可以找到chunk中的 ChunkNum 和 blockAddress 兩個數據,通過 blockAddress 可以找到該 chunk 所屬的 block,然后將ChunkNum 添加到該 block 的 freepos 中,其他相應屬性更新。

使用方法:

復制代碼 代碼如下:

memoryPool * mp = new memoryPool (256);  
  char * s = (char *)mp->allocate();
  // 一些操作
  mp->freeMemory(s);    
  delete mp;

不足:

沒考慮線程安全問題,該實現方案在單線程下可以正常運行。

程序源代碼:

復制代碼 代碼如下:

#include <iostream>
#include <queue>
#include <string.h>
#include <ctime>
using namespace std;

struct block {
    block * next;
    unsigned int numofChunks;//指向下一個block指針
    unsigned int numofFreeChunks;//剩余free的chunk數量
    unsigned int blockNum;//該block的編號
    char * data;
    //記錄可用chunk序號
    queue<int> freepos;
    block(unsigned int _numofChunks ,unsigned int _chunkSize, unsigned int _blockNum){
        numofChunks =  _numofChunks;
        numofFreeChunks = _numofChunks;
        blockNum = _blockNum;
        next = NULL;
        data = new char [numofChunks * (sizeof(unsigned int) + sizeof(void *) + _chunkSize)];
        char * p = data;
        //每個chunk的結構:4byte的chunk序號 + 4byte的所屬block地址 + 真正的數據
        for(int i=0;i<numofChunks;i++){
            char * ptr = p + i * (_chunkSize +  sizeof(unsigned int) + sizeof(void *));
            unsigned int * num = (unsigned int *)(ptr);
            *num = i;
            ptr += sizeof(void *);
            int * blockpos = (int *) ptr;
            *blockpos = (int)this;
            freepos.push(i);
        }
    }
    ~block(){
        delete [] data;
    }
};


class memoryPool {
public :
    memoryPool(unsigned int _chunkSize = 256, unsigned int _initNumofChunks = 4096, unsigned int _steps = 64){
        initNumofChunks = _initNumofChunks;
        chunkSize = _chunkSize;
        steps = _steps;
        numofBlocks = steps;
        //創建內存池時,初始化一定數量的內存空間
        block * p = new block(initNumofChunks, chunkSize, 0);
        blocksPtr = p;
        for(int i=1;i<steps;i++){
            p->next = new block(initNumofChunks, chunkSize, i);
            p = p->next;
            blocksPtrTail = p;
        }
        firstHasFreeChunksBlock = blocksPtr;
    }
    ~memoryPool(){
        block  * p = blocksPtr;
        while(blocksPtr!=NULL){
            p = blocksPtr->next;
            delete blocksPtr;
            blocksPtr = p;
        }
    }

    /*
    從firstHasFreeChunksBlock開始查找第一個有free位置的block,
    如果找到,則則獲取該block的freepos的對首元素,
    返回該元素序號對應的chunk的數據地址,并將freepos的隊首元素彈出,
    其他相關屬性更新。如果找不到,則新增steps個chunk,再重復上面的過程。
    */
    void * allocate(){
        block * p = firstHasFreeChunksBlock;
        while(p != NULL && p->numofFreeChunks <= 0) p = p->next;
        if(p == NULL){
            p = blocksPtrTail;
            increaseBlocks();
            p = p->next;
            firstHasFreeChunksBlock = p;
        }
        unsigned int pos =  p->freepos.front();
        void * chunkStart = (void *)(p->data + pos * (chunkSize +  sizeof(unsigned int) + sizeof(void *)));
        void * res = chunkStart + sizeof(unsigned int) + sizeof(void *);
        p->freepos.pop();
        p->numofFreeChunks --;
        return res;
    }

    void increaseBlocks(){
        block * p = blocksPtrTail;
        for(int i=0; i<steps; i++){
            p->next = new block(initNumofChunks, chunkSize, numofBlocks);
            numofBlocks++;
            p = p->next;
            blocksPtrTail = p;
        }
    }
    /*
    傳入待釋放的地址指針_data,
    通過對_data的地址移動可以找到chunk中的ChunkNum和blockAddress兩個數據,
    通過blockAddress可以找到該chunk所屬的block,
    然后將ChunkNum添加到該block的freepos中,其他相應屬性更新。
    */
    void freeMemory(void * _data){
        void * p = _data;
        p -= sizeof(void *);
        int * blockpos = (int *) p;
        block * b = (block *) (*blockpos);
        p -= sizeof(unsigned int);
        int * num = (int *) p;
        b->freepos.push(*num);
        b->numofFreeChunks ++;
        if (b->numofFreeChunks > 0 && b->blockNum < firstHasFreeChunksBlock->blockNum)
            firstHasFreeChunksBlock = b;
    }

private :
    unsigned int initNumofChunks; //每個block的chunk數量
    unsigned int chunkSize;//每個chunk的數據大小
    unsigned int steps;//每次擴展的chunk數量
    unsigned int numofBlocks;//當前管理多少個blocks
    block * blocksPtr;//指向起始block
    block * blocksPtrTail;//指向末尾block
    block * firstHasFreeChunksBlock;//指向第一個不為空的block
};

//test
void echoPositionNum(char * p){
    p -= (sizeof(void *) + sizeof(unsigned int));
    int * num = (int *) p;
    cout<<*num<<endl;
}

//測試
void test0(){
    memoryPool mp;
    char * s1 = (char *)mp.allocate();
    char * s2 = (char *)mp.allocate();

    char str [256];
    char str2 [256];
    char str3 [256];
    for(int i=0; i<255; i++) {
        str[i] = 'a';str2[i] = 'b';str3[i] = 'c';
    }
    str[255] = '/0';
    str2[255] = '/0';
    strcpy(s1,str);
    strcpy(s2,str2);
    str3[255] = '/0';
    echoPositionNum(s1);

    cout<<s1<<endl;
    mp.freeMemory(s1);
    echoPositionNum(s2);
    cout<<s2<<endl;
    char * s3 = (char *)mp.allocate();
    strcpy(s3,str3);

    echoPositionNum(s3);
    cout<<s3<<endl;

}

void test1(){
    clock_t clock_begin = clock();
    const int N = 50000;
    char * s[N];
    int round = 100;
    while(round>=0){
        round --;
        for(int i=0;i<N;i++){
            s[i] = new char[256];
        }
        for(int i=0;i<N;i++){
             delete [] s[i];
        }
    }
    clock_t clock_end = clock();
    cout<<"Time cost/t"<<clock_end - clock_begin<<endl;
}

void test2(){

    memoryPool mp(256);
    clock_t clock_begin = clock();
    const int N = 50000;
    char * s[N];
    int round = 100;
    while(round>=0){
        round --;
        for(int i=0;i<N;i++){
            s[i] = (char *)mp.allocate();
        }
        for(int i=0;i<N;i++){
            mp.freeMemory(s[i]);
        }
    }
    clock_t clock_end = clock();
    cout<<"Time cost/t"<<clock_end - clock_begin<<endl;

}
int main()
{
    test0();
    test1();
    test2();
    return 0;
}


運行結果:

image

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
色与欲影视天天看综合网| 欧美成人全部免费| 亚洲成人免费网站| 国产精品久久久久久久久免费| 亚洲free性xxxx护士hd| 国产在线98福利播放视频| 成人做爽爽免费视频| 97成人精品视频在线观看| 亚洲欧美日韩高清| 人人做人人澡人人爽欧美| 91亚洲精品视频| 久久精品国产久精国产一老狼| 韩国三级日本三级少妇99| 97精品在线视频| 国产精品久久久精品| 日韩一区av在线| 亚洲男人天堂2019| 精品国产欧美一区二区三区成人| 精品美女永久免费视频| 91免费欧美精品| 欧美激情a∨在线视频播放| 69av在线视频| 午夜精品一区二区三区av| 尤物九九久久国产精品的分类| 欧美黄色性视频| 中文字幕一区日韩电影| 中文字幕亚洲一区在线观看| 91理论片午午论夜理片久久| 91精品成人久久| 国模gogo一区二区大胆私拍| 久久久久久18| 亚洲欧洲黄色网| 欧美大片网站在线观看| 日韩精品在线观看一区二区| 97精品国产97久久久久久| 日韩电影大片中文字幕| 欧美激情视频一区| 久久色在线播放| 日韩中文字幕欧美| 亚洲国产美女精品久久久久∴| 成人国产在线激情| 久久精品亚洲国产| 国产精品高潮在线| 日韩欧美在线观看| 久久久久久国产三级电影| 亚洲乱码国产乱码精品精| 欧美成人精品不卡视频在线观看| 97超级碰碰人国产在线观看| 亚洲最新中文字幕| 欧美性猛交xxxx免费看| 欧美国产日韩xxxxx| 久久久久日韩精品久久久男男| 国产精品免费久久久| 国产精品高潮呻吟久久av野狼| 日韩暖暖在线视频| 国内精品小视频在线观看| 久久久女人电视剧免费播放下载| 亚洲最大福利网站| 欧美一级黑人aaaaaaa做受| 亚洲国产欧美久久| 亚洲一区免费网站| 日韩av在线电影网| 国产精品久久久久久久久男| 日韩精品视频观看| 日日狠狠久久偷偷四色综合免费| 日韩毛片在线观看| 美女黄色丝袜一区| 欧美主播福利视频| 欧美国产日韩一区二区在线观看| 亚洲激情视频网站| 欧美成人sm免费视频| 国产精品爽爽ⅴa在线观看| 欧美激情欧美激情在线五月| 成人黄色片网站| 日产精品久久久一区二区福利| yellow中文字幕久久| 色婷婷成人综合| 亚洲精品国产精品国自产观看浪潮| 亚洲一区美女视频在线观看免费| 欧美一级大胆视频| 亚洲欧洲高清在线| 日韩欧美大尺度| 精品久久久一区二区| 精品无人区乱码1区2区3区在线| 深夜福利一区二区| 国产一区二区香蕉| 国产在线拍揄自揄视频不卡99| 欧美成人一区在线| 97精品在线视频| 欧美日韩在线看| 久久久久久久av| 亚洲免费成人av电影| 欧美精品免费看| 日韩在线视频观看| 日韩黄色在线免费观看| 美女av一区二区| 国内精品美女av在线播放| 亚洲欧美在线一区二区| 国产精品99蜜臀久久不卡二区| 国产亚洲精品91在线| 精品欧美aⅴ在线网站| 7m精品福利视频导航| 91精品美女在线| 最近中文字幕2019免费| 久久久精品久久久久| 精品国内自产拍在线观看| 欧洲精品久久久| 亚洲综合色av| 欧美成人黑人xx视频免费观看| 久久6精品影院| 国内外成人免费激情在线视频网站| 国产精品久久久久久久9999| 国产精品久久久久久婷婷天堂| 中文字幕一区日韩电影| 欧美在线激情网| 一本色道久久88综合亚洲精品ⅰ| 久久久999国产精品| 国产精品成人在线| 日韩电影网在线| 亚洲性av在线| 国产欧美一区二区三区久久人妖| 亚洲国产精品国自产拍av秋霞| 久久中文久久字幕| 亚洲自拍偷拍第一页| 国产一区二区在线免费| 一区二区三区天堂av| 日韩经典第一页| 欧美亚洲视频在线观看| 国产区精品视频| 久久久久久国产精品| 大荫蒂欧美视频另类xxxx| 91麻豆国产精品| 国产精品视频久久久| 欧美一级在线亚洲天堂| 欧美日韩电影在线观看| 日韩女在线观看| 欧美黑人xxx| 中文日韩在线观看| 欧美大尺度电影在线观看| 亚洲成人精品av| 午夜精品一区二区三区在线视| 国产综合福利在线| 欧美区在线播放| 成人免费在线网址| 亚洲伊人成综合成人网| 国产精品视频最多的网站| www.日韩不卡电影av| 欧美精品videosex牲欧美| 中文字幕在线观看亚洲| 欧美又大粗又爽又黄大片视频| 精品视频中文字幕| 日韩黄色在线免费观看| 亚洲石原莉奈一区二区在线观看| 成人黄色免费在线观看| 日韩精品欧美国产精品忘忧草| 日韩精品在线观看一区| 日本国产欧美一区二区三区| 亚洲综合在线中文字幕| 亚洲视频电影图片偷拍一区| 日本一区二区在线免费播放| 日韩网站在线观看| 久久精品国产一区| 亚洲综合中文字幕在线观看| 中文字幕国产日韩|