国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

(內(nèi)存池) 基于嵌入式指針的簡(jiǎn)單內(nèi)存池

這篇具有很好參考價(jià)值的文章主要介紹了(內(nèi)存池) 基于嵌入式指針的簡(jiǎn)單內(nèi)存池。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

前言

內(nèi)存池_百度百科 (baidu.com)

(Memory Pool)是一種內(nèi)存分配方式,又被稱(chēng)為固定大小區(qū)塊規(guī)劃(fixed-size-blocks allocation)。通常我們習(xí)慣直接使用new、malloc等API申請(qǐng)分配內(nèi)存,這樣做的缺點(diǎn)在于:由于所申請(qǐng)內(nèi)存塊的大小不定,當(dāng)頻繁使用時(shí)會(huì)造成大量的內(nèi)存碎片并進(jìn)而降低性能。

內(nèi)存池的實(shí)現(xiàn)方式多種多樣,而本文僅實(shí)現(xiàn)一個(gè)簡(jiǎn)單的內(nèi)存池,主要運(yùn)用到嵌入式指針。

嵌入式指針,指的在數(shù)據(jù)單元中,用一部分空間保存某一塊空間的地址信息。實(shí)現(xiàn)方式多種多樣。

本示例的代碼量非常少,但能夠滿(mǎn)足最基本的內(nèi)存池需要的操作。

Code

MemoryPool

#include <cassert>
#include <cstdint>

namespace lotus {
template <typename Type, size_t Element_Count>
class MemoryPool {
    using UNIT_TYPE = uint8_t;
    static constexpr size_t BLOCK_SIZE = sizeof(Type);

private:
    void* m_buffer = nullptr;
    void* m_freeHead = nullptr;

public:
    MemoryPool() {
        static_assert(sizeof(Type) >= sizeof(void*), "size is to small");
        m_buffer = malloc(BLOCK_SIZE * Element_Count);
        m_freeHead = nullptr;

        for (size_t i = 0; i < Element_Count; i += 1) {
            void* index = (UNIT_TYPE*)m_buffer + (i * BLOCK_SIZE);
            *(void**)(index) = m_freeHead;
            m_freeHead = index;
        }
    }

    ~MemoryPool() {
        if (m_buffer) {
            free(m_buffer);
            m_buffer = nullptr;
        }
        if (m_freeHead) {
            m_freeHead = nullptr;
        }
    }

public:
    void* allocate() {
        assert(m_freeHead);
        void* res = m_freeHead;
        m_freeHead = (void*)(*(void**)m_freeHead);
        return res;
    }

    void deallocate(void* p) noexcept {
        *(void**)p = m_freeHead;
        m_freeHead = p;
    }
};
}  // namespace lotus

Test

#include <iostream>

namespace lotus {
template <typename Type, size_t Element_Count>
class MemoryPool {
    // ...
}
}

int main() {
    using Tp = long long;
    lotus::MemoryPool<Tp, 100U> pool;

    {
        Tp* p1 = (Tp*)pool.allocate();
        *p1 = 123;
        printf("p = %p\t val = %lld\n", p1, *p1);
        Tp* p2 = (Tp*)pool.allocate();
        *p2 = 123456;
        printf("p = %p\t val = %lld\n", p2, *p2);

        pool.deallocate(p1);
        printf("after free p1\n");
        Tp* p3 = (Tp*)pool.allocate();
        printf("p = %p\t val = %lld\n", p3, *p3);
    }

    {
        printf(">> show near allocate()\n");
        for (int i = 0; i < 10; i += 1) {
            Tp* p = (Tp*)pool.allocate();
            printf("p = %p\t pval = %x\n", p, *p);
        }
    }
}

簡(jiǎn)單講解

應(yīng)用方式

將數(shù)據(jù)類(lèi)型和類(lèi)型單元數(shù)量作為模板參數(shù)確定

每次void* allocate()獲取一個(gè)單元空間。

每次void deallocate(void* p)釋放一個(gè)空間。請(qǐng)保證傳入的是void* allocate()中獲取的。


簡(jiǎn)單解釋一下本文使用嵌入式指針的方式:

// p是一個(gè)指針,信息是一個(gè)地址值
void* p;
// pp = (void**)(p) 將p的信息強(qiáng)轉(zhuǎn)為一個(gè)二級(jí)指針
// *pp 解引用,表示pp這塊地址`的內(nèi)容`
*(void**)(p);

參數(shù)

template <typename Type, size_t Element_Count>
// 數(shù)據(jù)類(lèi)型
Type
// 最大申請(qǐng)個(gè)數(shù)
Element_Count

// 保證每個(gè)內(nèi)存單元式8字節(jié)
using UNIT_TYPE = uint8_t;
// type的大小作為一個(gè)數(shù)據(jù)塊
static constexpr size_t BLOCK_SIZE = sizeof(Type);

// 總內(nèi)存指針
void* m_buffer = nullptr;
// 頭指針,時(shí)刻指向可分配出的內(nèi)存地址
void* m_freeHead = nullptr;

MemoryPool();

MemoryPool() {
    // 確保目前元素大小比指針大小大
    static_assert(sizeof(Type) >= sizeof(void*), "size is to small");
    // 一口氣申請(qǐng)大內(nèi)存
    m_buffer = malloc(BLOCK_SIZE * Element_Count);
    m_freeHead = nullptr;

    for (size_t i = 0; i < Element_Count; i += 1) {
        // 將大內(nèi)存分塊
        void* index = (UNIT_TYPE*)m_buffer + (i * BLOCK_SIZE);
        // !核心!嵌入式指針
        // 總體表現(xiàn)為每后一個(gè)空間都保存前一個(gè)空間的地址信息
        *(void**)(index) = m_freeHead;
        m_freeHead = index;
    }
}

~MemoryPool();

~MemoryPool() {
    // 釋放內(nèi)存
    if (m_buffer) {
        free(m_buffer);
        m_buffer = nullptr;
    }
    // 僅起視圖代理作用,不掌管內(nèi)存
    if (m_freeHead) {
        m_freeHead = nullptr;
    }
}

void* allocate();

void* allocate() {
    assert(m_freeHead);
    // 分配出去的地址
    void* res = m_freeHead;
    // 借助嵌入式指針,將head指向下一個(gè)空間
    m_freeHead = (void*)(*(void**)m_freeHead);
    return res;
}

void deallocate(void* p);

void deallocate(void* p) noexcept {
    // 嵌入式指針賦值
    // p的空間的地址保存head的信息
    *(void**)p = m_freeHead;
    // head更新為p
    m_freeHead = p;
}

測(cè)試效果

g++ (x86_64-posix-seh-rev0, Built by MinGW-W64 project) 7.3.0

p = 0000000000751d98     val = 123    
p = 0000000000751d90     val = 123456 
after free p1
p = 0000000000751d98     val = 7675272
>> show near allocate()
p = 0000000000751d88     pval = 751d80
p = 0000000000751d80     pval = 751d78
p = 0000000000751d78     pval = 751d70
p = 0000000000751d70     pval = 751d68
p = 0000000000751d68     pval = 751d60
p = 0000000000751d60     pval = 751d58
p = 0000000000751d58     pval = 751d50
p = 0000000000751d50     pval = 751d48
p = 0000000000751d48     pval = 751d40
p = 0000000000751d40     pval = 751d38

第一部分可以看出,將p1歸還后,再申請(qǐng)p3,獲得的還是p1的地址。

第一部分可以看出,申請(qǐng)出空間的內(nèi)容就是下一個(gè)空間的地址,如pval = 751d78的下一次申請(qǐng)為p = 0000000000751d78文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-666896.html




END

到了這里,關(guān)于(內(nèi)存池) 基于嵌入式指針的簡(jiǎn)單內(nèi)存池的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶(hù)投稿,該文觀(guān)點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 基于嵌入式linux的OpenSSL源碼移植(基于arm64)

    基于嵌入式linux的OpenSSL源碼移植(基于arm64)

    SSL是Secure Sockets Layer(安全套接層協(xié)議)的縮寫(xiě),可以在Internet上提供秘密性傳輸。Netscape公司在推出第一個(gè)Web瀏覽器的同時(shí),提出了SSL協(xié)議標(biāo)準(zhǔn)。其目標(biāo)是保證兩個(gè)應(yīng)用間通信的保密性和可靠性,可在服務(wù)器端和用戶(hù)端同時(shí)實(shí)現(xiàn)支持。已經(jīng)成為Internet上保密通訊的工業(yè)標(biāo)準(zhǔn)。

    2024年02月11日
    瀏覽(20)
  • 嵌入式培訓(xùn)機(jī)構(gòu)四個(gè)月實(shí)訓(xùn)課程筆記(完整版)-Linux系統(tǒng)編程第五天-Linux消息共享內(nèi)存(物聯(lián)技術(shù)666)

    ?更多配套資料CSDN地址:點(diǎn)贊+關(guān)注,功德無(wú)量。更多配套資料,歡迎私信。 物聯(lián)技術(shù)666_嵌入式C語(yǔ)言開(kāi)發(fā),嵌入式硬件,嵌入式培訓(xùn)筆記-CSDN博客 物聯(lián)技術(shù)666擅長(zhǎng)嵌入式C語(yǔ)言開(kāi)發(fā),嵌入式硬件,嵌入式培訓(xùn)筆記,等方面的知識(shí),物聯(lián)技術(shù)666關(guān)注機(jī)器學(xué)習(xí),arm開(kāi)發(fā),物聯(lián)網(wǎng),嵌入式硬件,單

    2024年02月01日
    瀏覽(22)
  • 嵌入式Linux驅(qū)動(dòng)開(kāi)發(fā) 04:基于設(shè)備樹(shù)的驅(qū)動(dòng)開(kāi)發(fā)

    嵌入式Linux驅(qū)動(dòng)開(kāi)發(fā) 04:基于設(shè)備樹(shù)的驅(qū)動(dòng)開(kāi)發(fā)

    前面文章 《嵌入式Linux驅(qū)動(dòng)開(kāi)發(fā) 03:平臺(tái)(platform)總線(xiàn)驅(qū)動(dòng)模型》 引入了資源和驅(qū)動(dòng)分離的概念,這篇文章將在前面基礎(chǔ)上更進(jìn)一步,引入設(shè)備樹(shù)的概念。 在平臺(tái)總線(xiàn)驅(qū)動(dòng)模型中資源和驅(qū)動(dòng)已經(jīng)從邏輯上和代碼組織上進(jìn)行了分離,但每次調(diào)整資源還是會(huì)涉及到內(nèi)核,所以現(xiàn)

    2024年02月16日
    瀏覽(27)
  • 嵌入式培訓(xùn)機(jī)構(gòu)四個(gè)月實(shí)訓(xùn)課程筆記(完整版)-Linux系統(tǒng)編程第五天-Linux消息共享內(nèi)存練習(xí)題(物聯(lián)技術(shù)666)

    ??更多配套資料CSDN地址:點(diǎn)贊+關(guān)注,功德無(wú)量。更多配套資料,歡迎私信。 物聯(lián)技術(shù)666_嵌入式C語(yǔ)言開(kāi)發(fā),嵌入式硬件,嵌入式培訓(xùn)筆記-CSDN博客 物聯(lián)技術(shù)666擅長(zhǎng)嵌入式C語(yǔ)言開(kāi)發(fā),嵌入式硬件,嵌入式培訓(xùn)筆記,等方面的知識(shí),物聯(lián)技術(shù)666關(guān)注機(jī)器學(xué)習(xí),arm開(kāi)發(fā),物聯(lián)網(wǎng),嵌入式硬件

    2024年01月24日
    瀏覽(22)
  • 【嵌入式項(xiàng)目】基于A(yíng)RM+Linux的車(chē)載系統(tǒng)(完整工程資料源碼)

    【嵌入式項(xiàng)目】基于A(yíng)RM+Linux的車(chē)載系統(tǒng)(完整工程資料源碼)

    ????????基于A(yíng)RM+Linux的車(chē)載系統(tǒng)演示效果 基于A(yíng)RM+Linux的車(chē)載系統(tǒng) ????????本項(xiàng)目計(jì)劃主要應(yīng)用于家用,辦公等領(lǐng)域轎車(chē)中實(shí)施的基于物聯(lián)網(wǎng)云平臺(tái)的車(chē)載系統(tǒng)項(xiàng)目,既能夠?yàn)檐?chē)主在行駛過(guò)程中提供舒適的體驗(yàn),又能提供一定的安全保障。??? ????????基于A(yíng)RM+Linux的車(chē)

    2024年03月26日
    瀏覽(88)
  • 嵌入式學(xué)習(xí)之C語(yǔ)言指針部分復(fù)習(xí)

    嵌入式學(xué)習(xí)之C語(yǔ)言指針部分復(fù)習(xí)

    今天主要把C語(yǔ)言的指針部分再次認(rèn)真的復(fù)習(xí)了一下,對(duì)于指針的整體框架有了更加深刻的理解,特別要重點(diǎn)區(qū)分函數(shù)指針,指針函數(shù),數(shù)組指針,指針數(shù)組部分,對(duì)于這部分的應(yīng)用非常重要,而且C語(yǔ)言指針部分是面試的重中之重,所以要加強(qiáng)練習(xí)才行。 今天的學(xué)習(xí)是充滿(mǎn)動(dòng)

    2024年02月12日
    瀏覽(19)
  • 使用Yocto進(jìn)行嵌入式Linux開(kāi)發(fā)2 第一個(gè)基于Poky的系統(tǒng)

    使用Yocto進(jìn)行嵌入式Linux開(kāi)發(fā)2 第一個(gè)基于Poky的系統(tǒng)

    Ubuntu: Fedora 在我們的開(kāi)發(fā)主機(jī)系統(tǒng)上安裝了所需的軟件包后,我們可以使用 Git 下載當(dāng)前 LTS 版本的 Poky 源代碼,命令如下: 下載完成后,poky 目錄中的內(nèi)容如下: 在poky目錄中存在oe-init-build-env腳本,用于設(shè)置構(gòu)建環(huán)境。 這里,[build-directory] 是一可選參數(shù),用于指定配置環(huán)境

    2024年02月08日
    瀏覽(56)
  • 基于RK3588的嵌入式linux系統(tǒng)開(kāi)發(fā)(二)——uboot源碼移植及編譯

    基于RK3588的嵌入式linux系統(tǒng)開(kāi)發(fā)(二)——uboot源碼移植及編譯

    ??????? 由于官方的SDK占用空間較大(大約20GB左右),需要聯(lián)系相關(guān)供應(yīng)商提供,且官方的SDK通過(guò)各種腳本文件進(jìn)行集成編譯,難以理解系統(tǒng)開(kāi)發(fā)的詳細(xì)過(guò)程。本章介紹直接從官方Github網(wǎng)站下載源碼進(jìn)行移植,進(jìn)行uboot移植及編譯,具體內(nèi)容如下所述: 1.進(jìn)入官方的github網(wǎng)

    2024年01月16日
    瀏覽(28)
  • 嵌入式開(kāi)發(fā)——DMA外設(shè)到內(nèi)存

    嵌入式開(kāi)發(fā)——DMA外設(shè)到內(nèi)存

    加強(qiáng)理解DMA數(shù)據(jù)傳輸過(guò)程 加強(qiáng)掌握DMA的初始化流程 掌握DMA數(shù)據(jù)表查詢(xún) 理解源和目標(biāo)的配置 理解數(shù)據(jù)傳輸特點(diǎn) 能夠動(dòng)態(tài)配置源數(shù)據(jù) 需求 實(shí)現(xiàn)串口的數(shù)據(jù)接收,要求采用dma的方式。 數(shù)據(jù)交互流程 CPU配置好DMA 外部數(shù)據(jù)發(fā)送給串口外設(shè) 串口外設(shè)觸發(fā)中斷 CPU處理中斷邏輯,通知

    2024年02月03日
    瀏覽(22)
  • 嵌入式Linux實(shí)戰(zhàn)開(kāi)發(fā)之項(xiàng)目總體概述(基于IMX6ULL)

    嵌入式Linux實(shí)戰(zhàn)開(kāi)發(fā)之項(xiàng)目總體概述(基于IMX6ULL)

    現(xiàn)在越來(lái)越多的智能設(shè)備融入到我們的生活,然而,豐富的設(shè)備之下也是有一套基本的運(yùn)行框架,只是根據(jù)不同的需求增減相應(yīng)的功能從而滿(mǎn)足自身的需要。而電子產(chǎn)品量產(chǎn)工具項(xiàng)目,就是實(shí)現(xiàn)基礎(chǔ)的功能,可以作為一個(gè)基礎(chǔ)的模版,學(xué)成之后便可進(jìn)行擴(kuò)展,根據(jù)自身需求,

    2024年02月13日
    瀏覽(85)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包