stl記憶體池學習(二) 走近記憶體池

2021-05-25 20:55:14 字數 1942 閱讀 6056

這一節學習基礎知識:所用到的資料結構。首先看記憶體池的介面:

code:

#ifndef _mem_pool_h

#define _mem_pool_h

static

size_t __freelist_index(size_t bytes);    

static

size_t __round_up(size_t bytes);   

static

void *mem_malloc(size_t n);   

static

void mem_free(void *p, size_t n);   

static

void *mem_realloc(void* ptr, size_t new_sz, size_t old_sz)   

static

void *refill(size_t n);   

static

char *chunk_alloc(size_t size, int *nobjs);   

#endif

用到的常量與變數:

code:

#define __max_bytes 128     /* 小型區塊的上限 */

#define __align 8           /* 小型區塊的上調邊界 */

#define __nfreelists __max_bytes / __align /* 鍊錶個數 */

obj *free_list[__nfreelists]; /* 自由鍊錶 */

static

char *start_free;  /* 記憶體池起始位置 */

static

char *end_free;    /* 記憶體池結束位置 */

static

size_t heap_size;  /* 記憶體池大小 */

這裡值得一提的是共用體obj,定義如下:

code:

typedef

union obj obj;  

一般情況下我們構建單鏈表時需要建立如下的乙個結構體:

struct obj ;

使用者申請12位元組的空間時使用時如下方式:

obj *pj = (obj *)malloc(12 +  sizeof(struct obj));

pj->next = null;

pj->p = (char*)p + sizeof(struct obj);

pj->size = 12;

但是採用這種方式有個缺點就是我們需要花費額外的開銷(記錄指向下乙個結點的指標和大小),我們可以通過直接定位鍊錶在free_list陣列中的位置來減掉 size 的開銷,因為 free_list[0] 指向的是8 bytes的區塊,free_list[1] 指向的是16 bytes的區塊……。但仍需承擔 next 和 p 指標的開銷。

當我們採用

union obj ;

時,sizeof(obj)的大小為4,當然我們更不需負擔這4個位元組的開銷。因為我們可以充分利用union的特性——同一時刻只存在乙個變數。當我們構建空閒鍊錶時,我們通過free_list_link指向下乙個obj,當把這個obj分配出去的時候,我們直接返回client_data的位址。這樣我們就不會在使用者申請的空間上新增任何東西,達到了一物二用的結果。

接下來看幾個簡單的函式:

code:

static

size_t  __freelist_index(size_t bytes)   

static

size_t __round_up(size_t bytes)     

__freelist_index的作用是函式根據區塊的大小,決定使用第n號free-list。n從0算起。__round_up用於將bytes上調至 __align 的倍數。

接下來要進入幾個主要的函式學習了。

stl記憶體池學習(一) 記憶體池初認識

序號 0123 4567 891011 1213 1415 串接區塊816 2432 4048 5664 7280 8896 104112 120128 範圍1 8 9 16 17 24 25 32 33 40 41 48 49 56 57 64 65 72 73 80 81 88 89 96 97...

stl記憶體池學習(一) 記憶體池初認識

序號 0123 4567 891011 1213 1415 串接區塊816 2432 4048 5664 7280 8896 104112 120128 範圍1 8 9 16 17 24 25 32 33 40 41 48 49 56 57 64 65 72 73 80 81 88 89 96 97...

STL記憶體池講解

簡單說下 設計記憶體池的目的主要是為了解決在一些特殊的場合 比如 網路程式設計時接受資料報 頻繁的建立和銷毀 造成的大量的記憶體碎片和降低效率。在stl的記憶體池中可以看到 它的實現是利用了乙個自由鍊錶陣列 obj free lists 陣列中每個元素都是乙個自由鍊錶的頭指標 它指向乙個由多個記憶體...