最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

基于一個(gè)簡(jiǎn)單定長(zhǎng)內(nèi)存池的實(shí)現(xiàn)方法詳解

 更新時(shí)間:2013年05月07日 10:32:18   作者:  
本篇文章對(duì)一個(gè)簡(jiǎn)單定長(zhǎng)內(nèi)存池的實(shí)現(xiàn)方法進(jìn)行了詳細(xì)的分析介紹。需要的朋友參考下

    主要分為 3 個(gè)部分,memoryPool 是管理內(nèi)存池類,block 表示內(nèi)存塊,chunk 表示每個(gè)存儲(chǔ)小塊。它們之間的關(guān)系為,memoryPool 中有一個(gè)指針指向某一起始 block,block 之前通過(guò) next 指針構(gòu)成鏈表結(jié)構(gòu)的連接,每個(gè) block 包含指定數(shù)量的 chunk。每次分配內(nèi)存的時(shí)候,分配 chunk 中的數(shù)據(jù)地址。

內(nèi)存池設(shè)計(jì)文檔

主要數(shù)據(jù)結(jié)構(gòu)設(shè)計(jì):

Block:

復(fù)制代碼 代碼如下:

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

MemoryPool:
復(fù)制代碼 代碼如下:

class memoryPool {
    unsigned int initNumofChunks; //每個(gè)block的chunk數(shù)量
    unsigned int chunkSize;//每個(gè)chunk的數(shù)據(jù)大小
    unsigned int steps;//每次擴(kuò)展的chunk數(shù)量
    unsigned int numofBlocks;//當(dāng)前管理多少個(gè)blocks
    block * blocksPtr;//指向起始block
    block * blocksPtrTail;//指向末尾block
    block * firstHasFreeChunksBlock;//指向第一個(gè)不為空的block
};

Chunk:

ChunkNum:該 chunk 所在 block 里的編號(hào)

blockAddress: 該 chunk 所對(duì)應(yīng)的 block,主要用于 free 這個(gè) chunk 的時(shí)候,能夠快速找到所屬 block,并進(jìn)行相應(yīng)更新

data:實(shí)際供使用的數(shù)據(jù)起始位置

關(guān)鍵操作說(shuō)明:

內(nèi)存分配:

從 firstHasFreeChunksBlock 開始查找第一個(gè)有 free 位置的 block,如果找到,則則獲取該 block 的 freepos 的隊(duì)首元素,返回該元素序號(hào)對(duì)應(yīng)的 chunk 的數(shù)據(jù)地址,并將 freepos 的隊(duì)首元素彈出,其他相關(guān)屬性更新。如果找不到,則新增 steps 個(gè) chunk,再重復(fù)上面的過(guò)程。

內(nèi)存釋放:

傳入待釋放的地址指針p,通過(guò)對(duì)p的地址移動(dòng)可以找到chunk中的 ChunkNum 和 blockAddress 兩個(gè)數(shù)據(jù),通過(guò) blockAddress 可以找到該 chunk 所屬的 block,然后將ChunkNum 添加到該 block 的 freepos 中,其他相應(yīng)屬性更新。

使用方法:

復(fù)制代碼 代碼如下:

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

不足:

沒(méi)考慮線程安全問(wèn)題,該實(shí)現(xiàn)方案在單線程下可以正常運(yùn)行。

程序源代碼:

復(fù)制代碼 代碼如下:

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

struct block {
    block * next;
    unsigned int numofChunks;//指向下一個(gè)block指針
    unsigned int numofFreeChunks;//剩余free的chunk數(shù)量
    unsigned int blockNum;//該block的編號(hào)
    char * data;
    //記錄可用chunk序號(hào)
    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;
        //每個(gè)chunk的結(jié)構(gòu):4byte的chunk序號(hào) + 4byte的所屬block地址 + 真正的數(shù)據(jù)
        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;
        //創(chuàng)建內(nèi)存池時(shí),初始化一定數(shù)量的內(nèi)存空間
        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開始查找第一個(gè)有free位置的block,
    如果找到,則則獲取該block的freepos的對(duì)首元素,
    返回該元素序號(hào)對(duì)應(yīng)的chunk的數(shù)據(jù)地址,并將freepos的隊(duì)首元素彈出,
    其他相關(guān)屬性更新。如果找不到,則新增steps個(gè)chunk,再重復(fù)上面的過(guò)程。
    */
    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,
    通過(guò)對(duì)_data的地址移動(dòng)可以找到chunk中的ChunkNum和blockAddress兩個(gè)數(shù)據(jù),
    通過(guò)blockAddress可以找到該chunk所屬的block,
    然后將ChunkNum添加到該block的freepos中,其他相應(yīng)屬性更新。
    */
    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; //每個(gè)block的chunk數(shù)量
    unsigned int chunkSize;//每個(gè)chunk的數(shù)據(jù)大小
    unsigned int steps;//每次擴(kuò)展的chunk數(shù)量
    unsigned int numofBlocks;//當(dāng)前管理多少個(gè)blocks
    block * blocksPtr;//指向起始block
    block * blocksPtrTail;//指向末尾block
    block * firstHasFreeChunksBlock;//指向第一個(gè)不為空的block
};

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

//測(cè)試
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;
}


運(yùn)行結(jié)果:

image

相關(guān)文章

  • VC編程控件類HTControl之CHTGDIManager GDI資源管理類用法解析

    VC編程控件類HTControl之CHTGDIManager GDI資源管理類用法解析

    這篇文章主要介紹了VC編程控件類HTControl之CHTGDIManager GDI資源管理類用法解析,需要的朋友可以參考下
    2014-08-08
  • C++控制臺(tái)實(shí)現(xiàn)隨機(jī)生成路徑迷宮游戲

    C++控制臺(tái)實(shí)現(xiàn)隨機(jī)生成路徑迷宮游戲

    這篇文章主要為大家詳細(xì)介紹了C++控制臺(tái)實(shí)現(xiàn)隨機(jī)生成路徑迷宮游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-05-05
  • 使用C++的inipp庫(kù)處理配置文件.ini的示例詳解

    使用C++的inipp庫(kù)處理配置文件.ini的示例詳解

    一個(gè)ini文件由多個(gè)節(jié)section組成,每個(gè)節(jié)由多個(gè)鍵值對(duì)組成,本文給大家介紹了使用第三方庫(kù)inipp來(lái)操作ini文件,文中通過(guò)代碼示例講解的非常詳細(xì),需要的朋友可以參考下
    2024-01-01
  • 詳解c++種gmock單元測(cè)試框架

    詳解c++種gmock單元測(cè)試框架

    這篇文章我們給大家分享了關(guān)于c++種gmock單元測(cè)試框架的相關(guān)知識(shí)點(diǎn)內(nèi)容,有興趣的朋友們學(xué)習(xí)下。
    2018-08-08
  • 基于epoll的多線程網(wǎng)絡(luò)服務(wù)程序設(shè)計(jì)

    基于epoll的多線程網(wǎng)絡(luò)服務(wù)程序設(shè)計(jì)

    這篇文章主要為大家詳細(xì)介紹了基于epoll的多線程網(wǎng)絡(luò)服務(wù)程序設(shè)計(jì),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • C++詳解多線程中的線程同步與互斥量

    C++詳解多線程中的線程同步與互斥量

    線程間如何通信同步?一些伙伴好奇線程間的通信及同步方法,沒(méi)關(guān)系,下面小編就繼續(xù)給大家科普下線程間通信及同步的方法以及互斥量
    2022-05-05
  • 在std::thread中創(chuàng)建并管理QEventLoop的全面解析

    在std::thread中創(chuàng)建并管理QEventLoop的全面解析

    QEventLoop的工作原理可以簡(jiǎn)單地理解為一個(gè)無(wú)限循環(huán),它會(huì)不斷地檢查是否有新的事件需要處理,如果有,就將事件從事件隊(duì)列中取出,然后找到相應(yīng)的事件處理器進(jìn)行處理,這篇文章主要介紹了在std::thread中創(chuàng)建并管理QEventLoop的全面指南,需要的朋友可以參考下
    2023-06-06
  • 關(guān)于C++讀入數(shù)字按位取出與進(jìn)制轉(zhuǎn)換問(wèn)題(典型問(wèn)題)

    關(guān)于C++讀入數(shù)字按位取出與進(jìn)制轉(zhuǎn)換問(wèn)題(典型問(wèn)題)

    這篇文章主要介紹了關(guān)于C++讀入數(shù)字按位取出與進(jìn)制轉(zhuǎn)換問(wèn)題,是一個(gè)非常典型的問(wèn)題,本文通過(guò)實(shí)例舉例給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2020-02-02
  • 最新評(píng)論

    元谋县| 利川市| 赣榆县| 泸定县| 西盟| 常山县| 墨江| 武隆县| 平顺县| 武安市| 二连浩特市| 龙陵县| 威远县| 黄陵县| 邢台县| 泗阳县| 广昌县| 乐清市| 临汾市| 泰宁县| 平遥县| 文成县| 嵊泗县| 双江| 建水县| 章丘市| 治多县| 卓资县| 汶川县| 承德市| 宜黄县| 桂林市| 榆中县| 平谷区| 花垣县| 平乐县| 胶南市| 绵阳市| 靖江市| 临清市| 云梦县|