VS 2010 STL deque原始碼分析

2021-09-26 04:22:24 字數 3079 閱讀 6518

deque 即雙端佇列,與vector相比,此容器多出了pop_front()和push_front()這兩個操作,即在首部的增刪操作;而與list相比,deque多出了對容器元素的隨機訪問功能。

網上也有很多關於deque原始碼分析的文章,不過大部分都是繼承自侯捷《stl原始碼分析》中關於deque原始碼的講解。鮮有vs版本 stl deque原始碼的講解,現在就來看看vs版本是如何實現的。

若是讓我自己實現乙個簡單的deque,何不分配兩塊記憶體,一塊用來分配給push_back,另一塊分配給push_front,若是記憶體不夠了,就各自重新分配記憶體。插入或刪除操作,只需移動元素即可。然後分別記錄push_back與push_front的元素個數,這樣就可以隨機訪問了。我這個思路豈不是很簡單。

vs用到了二級指標,二級指標裡存放的一級指標是連續的,每乙個一級指標存放一塊記憶體的位址,這塊記憶體(就是陣列,連續的)存放的是我們push_back與push_front的元素。

假若把所有block中一級指標指向的記憶體看成連續的,那麼在這塊大記憶體中,一邊是push_back進來的,一邊是push_front進來的。

當然了,分界點,未必是0與31號記憶體,也可能是6,7號記憶體。(deque是模板類,若是模板引數是int,那麼二級指標就是int*)。

// template class _deque_val

templateclass _deque_val

: public _container_base12

;

在deque的基類,_deque_val中,有上面那幾個成員變數。_map就是二級指標,我們以deque用來存放int型元素舉例,那麼_map就是int**型別的變數。_mapsize就是一級指標數量,或者說用來存放我們元素的記憶體塊的數量。_myoff已經在圖2中標註,它就是我們第乙個元素的記憶體號,其實它就可以起到區分push_back元素與push_front元素的作用。_mysize就是deque中存在元素的數量。除了上面幾個成員變數還有兩個巨集,也很重要。

// deque parameters

#define _dequemapsiz 8 /* minimum map size, at least 1 */

#define _dequesiz (sizeof (value_type) <= 1 ? 16 \

: sizeof (value_type) <= 2 ? 8 \

: sizeof (value_type) <= 4 ? 4 \

: sizeof (value_type) <= 8 ? 2 \

: 1) /* elements per block (a power of 2) */

_dequemapsiz是_map最小的大小,_dequesiz是一級指標指向記憶體能分配元素的個數。這塊記憶體反正是16個位元組,那麼模板引數是int,那麼這個記憶體block就可以存放4個元素嘍。

當什麼時候需要增加一級指標的數量呢?當_myoff是4的倍數,並且元素數量<=容量減4 的時候,需要擴容了。

void _growmap(size_type _count)

else//情況2

//釋放push_front元素對應的block指標(一級指標)

_destroy_range(this->_map + _myboff, this->_map + this->_mapsize,

this->_almap);

//釋放二級記憶體_map

if (this->_map != 0)

this->_almap.deallocate(this->_map,

this->_mapsize); // free storage for old

this->_map = _newmap; // point at new

this->_mapsize += _count;

}

情況1:如圖3,當新分配記憶體大小,足以容納push_back元素

情況2:如圖4,當新分配記憶體大小,不 足以容納push_back元素,這時候就需要往分批拷貝。

push_back用到了兩個巨集_push_back_begin與_push_back_end,貼上**直接把巨集替換掉了。

void push_back(_ty&& _val)

push_front用到了兩個巨集_push_front_begin與_push_front_end,貼上**直接把巨集替換掉了。

void push_front(_ty&& _val)

迭代器裡面只有乙個成員變數,_myoff,即 offset of element in deque,意思就是相對於0號記憶體的位置,即記憶體號。假如現在有8個block,每個block容納4個元素,push_front了21次,那麼begin()返回的迭代器的_myoff應該為32-21==11。11號記憶體位置存放著我們第乙個元素。只有_myoff++就相當於迭代器++,就可以檢視後面那個記憶體了。

// template class _deque_const_iterator

templateclass _deque_const_iterator

: public _iterator_base12

;

iterator erase(const_iterator _first_arg,

const_iterator _last_arg)

else

return (begin() + _off);

}

VS2010 rdlc報表 不在依賴 資料來源

在傳統的vs2005與vs2008中,rdlc報表是必須依賴外在的資料集的,但是vs2010 rdlc 報表不在需要外在資料集,關鍵是因為rdlc報表 內建了乙個資料集,把rdlc報表 用xml方式開啟,自己可以按照xml的方式 設定乙個資料集如下方式,其中紅色的部分為多餘的部分,可以去掉.stco...

如何提高VS2010的效能,VS2010不再卡

教大家幾個技巧可以稍微讓你覺得它沒那麼卡!一 vs2010選項視覺體驗設定 工具 選項 環境 視覺體驗的勾選都去掉。不解釋,你懂得。不過還是建議開啟硬體加速 二 禁用intellisense 工具 選項 文字編輯器 c c 高階 禁用intellisense設為true 這個功能很好用。相較於vis...

Matlab R2010a和vs 2010混合程式設計

matlabr2010a與vs2010 c 混合程式設計成功,在vs2010 c 中能夠呼叫matlab的m函式,進行計算,得到正確結果,呼叫matlab中m函式轉化成的dll檔案 一 matlab編譯環境的設定 mex setup pleasechoose your compiler for bu...