關於容器與空間分配

2021-10-13 21:55:34 字數 2447 閱讀 1301

容器本質上的作用就是對資料的管理,整體來說就是對資料的增、刪、修改;但是結合了計算機的空間屬性,就又需要進行一次擴充套件,也就是對於計算機空間的管理:申請與釋放;

對於乙個元素的話,整個過程可以參考new的過程,且stl預設的空間分配器就是以new作為基礎進行實現,new的話,直接使用它會申請需要的空間並呼叫物件的建構函式並返回構造好物件的空間位址;他是分為兩個過程的,乙個過程是對空間的申請,另外乙個過程是對申請到的空間的物件構造;在c++中分別是operator new與placement new;

容器基於這樣的空間分配方式以及物件構造方式進行對資料的儲存以及管理;

stl預設的空間分配器為std::allocator;該類為乙個模板類,對應的原始碼位置為libstdc++-v3/include/bits/allocator.h;該模板類繼承另外乙個模板類,__allocator_base,該基類為乙個巨集,在libstdc++-v3/include/bits/c++allocator.h中定義,最終該基類指向/libstdc++-v3/include/ext/new_allocator.h;裡面有幾個介面,這些介面基本原理就是operator new和placement new的具體使用;而rebind則是該空間分配器繫結另外乙個型別進行返回。該空間分配器allocator介面的作用就是基於_tp作為基本單元,而後申請需要單位數的空間;該類原始碼如下:

templateclass new_allocator

;#if __cplusplus >= 201103l

// _glibcxx_resolve_lib_defects

// 2103. propagate_on_container_move_assignment

typedef std::true_type propagate_on_container_move_assignment;

#endif

new_allocator() _glibcxx_use_noexcept

new_allocator(const new_allocator&) _glibcxx_use_noexcept

templatenew_allocator(const new_allocator<_tp1>&) _glibcxx_use_noexcept

~new_allocator() _glibcxx_use_noexcept

pointer

address(reference __x) const _glibcxx_noexcept

const_pointer

address(const_reference __x) const _glibcxx_noexcept

// nb: __n is permitted to be 0. the c++ standard says nothing

// about what the return value is when __n == 0.

/** 申請到堆空間返回申請到空間的指標 */

pointer allocate(size_type __n, const void* = 0)

// __p is not permitted to be a null pointer.

void

deallocate(pointer __p, size_type)

size_type

max_size() const _glibcxx_use_noexcept

#if __cplusplus >= 201103l

templatevoid

construct(_up* __p, _args&&... __args)

templatevoid

destroy(_up* __p)

#else

// _glibcxx_resolve_lib_defects

// 402. wrong new expression in [some_] allocator::construct

/* placement new函式,也就是呼叫建構函式去初始化申請到的空間 */

void

construct(pointer __p, const _tp& __val)

/* 呼叫析構函式 */

void

destroy(pointer __p)

#endif

};/* 利用template模板去判斷兩個分配器是否是相同的分配器 */

templateinline bool

operator==(const new_allocator<_tp>&, const new_allocator<_tp>&)

templateinline bool

operator!=(const new_allocator<_tp>&, const new_allocator<_tp>&)

這樣,通過對_tp的型別繫結,在申請記憶體的時候直接申請需要的單位即可;

空間與位址分配

我們知道,可執行檔案中的 段和資料段都是由輸入的目標檔案中合併而來的。那麼鏈結器是如何將它們的各個段合併到輸出檔案?或者說,輸出檔案中的空間如何分配給輸入檔案的。最簡單的方案就是直接將各個目標檔案依次合併,但是這樣做輸出檔案將會有很多零散的段。這種做法非常浪費空間,因為每個段都需要有一定的位址和空間...

vector容器的動態分配空間

vector容器的底層實現基於陣列,裡面封裝了大量高效的方法,可以完美取代掉陣列。整個容器的核心實際上就是動態分配記憶體,也是其效能優於陣列的重要原因。下面重點解析它的核心函式push back函式 當陣列中增加乙個元素x的時候,先判斷是否還有備用空間 如果還有備用空間,則將當前指標的值設為x,並將...

記憶體空間與分配

1 記憶體分配錯誤 動態記憶體分配錯誤有兩種基本型別 記憶體錯誤和記憶體洩漏。1 記憶體錯誤 當乙個指標或者該指標所指向的記憶體單元成為無效單元,或者記憶體中分配的資料結構被破壞時,就會造成記憶體錯誤。指標未被初始化,指標被初始化為乙個無效位址,指標被不小心錯誤地修改,在與指標相關聯的記憶體區域被釋...