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

C++中std::allocator的使用案例詳解

 更新時間:2021年09月07日 15:49:54   作者:fengbingchun  
這篇文章主要介紹了C++中std::allocator的使用案例詳解,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下

標準庫中包含一個名為allocator的類,允許我們將分配和初始化分離。使用allocator通常會提供更好的性能和更靈活的內(nèi)存管理能力。

        new有一些靈活性上的局限,其中一方面表現(xiàn)在它將內(nèi)存分配和對象構(gòu)造組合在了一起。類似的,delete將對象析構(gòu)和內(nèi)存釋放組合在了一起。我們分配單個對象時,通常希望將內(nèi)存分配和對象初始化組合在一起。因為在這種情況下,我們幾乎肯定知道對象應(yīng)有什么值。當分配一大塊內(nèi)存時,我們通常計劃在這塊內(nèi)存上按需構(gòu)造對象。在此情況下,我們希望將內(nèi)存分配和對象構(gòu)造分離。這意味著我們可以分配大塊內(nèi)存,但只在真正需要時才真正執(zhí)行對象的創(chuàng)建操作(同時付出一定開銷)。一般情況下,將內(nèi)存分配和對象構(gòu)造組合在一起可能會導(dǎo)致不必要的浪費

        標準庫allocator類定義在頭文件memory中,它幫助我們將內(nèi)存分配和對象構(gòu)造分離開來它提供一種類型感知的內(nèi)存分配方法,它分配的內(nèi)存是原始的、未構(gòu)造的。類似vector,allocator是一個模板。為了定義一個allocator對象,我們必須指明這個allocator可以分配的對象類型。當一個allocator對象分配內(nèi)存時,它會根據(jù)給定的對象類型來確定恰當?shù)膬?nèi)存大小和對齊位置。allocator支持的操作,如下:

        allocatro分配的內(nèi)存是未構(gòu)造的(unconstructed)。我們按需要在此內(nèi)存中構(gòu)造對象。在新標準庫中,construct成員函數(shù)接受一個指針和零個或多個額外參數(shù),在給定位置構(gòu)造一個元素。額外參數(shù)用來初始化構(gòu)造的對象。類似make_shared的參數(shù),這些額外參數(shù)必須是與構(gòu)造的對象的類型相匹配的合法的初始化器。

        在早期版本的標準庫中,construct只接受兩個參數(shù):指向創(chuàng)建對象位置的指針和一個元素類型的值。因此,我們只能將一個元素拷貝到未構(gòu)造空間中,而不能用元素類型的任何其它構(gòu)造函數(shù)來構(gòu)造一個元素。還未構(gòu)造對象的情況下就使用原始內(nèi)存是錯誤的。為了使用allocator返回的內(nèi)存,我們必須用construct構(gòu)造對象。使用未構(gòu)造的內(nèi)存,其行為是未定義的。

        當我們用完對象后,必須對每個構(gòu)造的元素調(diào)用destroy來銷毀它們。函數(shù)destroy接受一個指針,對執(zhí)行的對象執(zhí)行析構(gòu)函數(shù)。我們只能對真正構(gòu)造了的元素進行destroy操作。一旦元素被銷毀后,就可以重新使用這部分內(nèi)存來保存其它string,也可以將其歸還給系統(tǒng)。釋放內(nèi)存通過調(diào)用deallocate來完成。我們傳遞給deallocate的指針不能為空,它必須指向由allocate分配的內(nèi)存。而且,傳遞給deallocate的大小參數(shù)必須與調(diào)用allocate分配內(nèi)存時提供的大小參數(shù)具有一樣的值。

        標準庫還為allocator類定義了兩個伴隨算法,可以在未初始化內(nèi)存中創(chuàng)建對象。它們都定義在頭文件memory中,如下:

        在C++中,內(nèi)存是通過new表達式分配,通過delete表達式釋放的。標準庫還定義了一個allocator類來分配動態(tài)內(nèi)存塊。分配動態(tài)內(nèi)存的程序應(yīng)負責釋放它所分配的內(nèi)存。內(nèi)存的正確釋放是非常容易出錯的地方:要么內(nèi)存永遠不會被釋放,要么在仍有指針引用它時就被釋放了。新的標準庫定義了智能指針類型------shared_ptr、unique_ptr和weak_ptr,可令動態(tài)內(nèi)存管理更為安全。對于一塊內(nèi)存,當沒有任何用戶使用它時,智能指針會自動釋放它?,F(xiàn)代C++程序應(yīng)盡可能使用智能指針。

        std::allocator是標準庫容器的默認內(nèi)存分配器。你可以替換自己的分配器,這允許你控制標準容器分配內(nèi)存的方式。

        以上內(nèi)容主要摘自:《C++Primer(Fifth Edition 中文版)》第12.2.2章節(jié)

下面是從其他文章中copy的測試代碼,詳細內(nèi)容介紹可以參考對應(yīng)的reference:

#include "allocator.hpp"
#include <iostream>
#include <memory>
#include <string>
#include <vector>
 
namespace allocator_ {
 
 
// reference: C++ Primer(Fifth Edition) 12.2.2
int test_allocator_1()
{
	std::allocator<std::string> alloc; // 可以分配string的allocator對象
	int n{ 5 };
	auto const p = alloc.allocate(n); // 分配n個未初始化的string
 
	auto q = p; // q指向最后構(gòu)造的元素之后的位置
	alloc.construct(q++); // *q為空字符串
	alloc.construct(q++, 10, 'c'); // *q為cccccccccc
	alloc.construct(q++, "hi"); // *q為hi
 
	std::cout << *p << std::endl; // 正確:使用string的輸出運算符
	//std::cout << *q << std::endl; // 災(zāi)難:q指向未構(gòu)造的內(nèi)存
	std::cout << p[0] << std::endl;
	std::cout << p[1] << std::endl;
	std::cout << p[2] << std::endl;
 
	while (q != p) {
		alloc.destroy(--q); // 釋放我們真正構(gòu)造的string
	}
 
	alloc.deallocate(p, n);
 
	return 0;
}
 
int test_allocator_2()
{
	std::vector<int> vi{ 1, 2, 3, 4, 5 };
 
	// 分配比vi中元素所占用空間大一倍的動態(tài)內(nèi)存
	std::allocator<int> alloc;
	auto p = alloc.allocate(vi.size() * 2);
	// 通過拷貝vi中的元素來構(gòu)造從p開始的元素
	/* 類似拷貝算法,uninitialized_copy接受三個迭代器參數(shù)。前兩個表示輸入序列,第三個表示
	這些元素將要拷貝到的目的空間。傳遞給uninitialized_copy的目的位置迭代器必須指向未構(gòu)造的
	內(nèi)存。與copy不同,uninitialized_copy在給定目的位置構(gòu)造元素。
	類似copy,uninitialized_copy返回(遞增后的)目的位置迭代器。因此,一次uninitialized_copy調(diào)用
	會返回一個指針,指向最后一個構(gòu)造的元素之后的位置。
	*/
	auto q = std::uninitialized_copy(vi.begin(), vi.end(), p);
	// 將剩余元素初始化為42
	std::uninitialized_fill_n(q, vi.size(), 42);
 
	return 0;
}
 
 
// reference: http://www.modernescpp.com/index.php/memory-management-with-std-allocator
int test_allocator_3()
{
	std::cout << std::endl;
 
	std::allocator<int> intAlloc;
 
	std::cout << "intAlloc.max_size(): " << intAlloc.max_size() << std::endl;
	int* intArray = intAlloc.allocate(100);
 
	std::cout << "intArray[4]: " << intArray[4] << std::endl;
 
	intArray[4] = 2011;
 
	std::cout << "intArray[4]: " << intArray[4] << std::endl;
 
	intAlloc.deallocate(intArray, 100);
 
	std::cout << std::endl;
 
	std::allocator<double> doubleAlloc;
	std::cout << "doubleAlloc.max_size(): " << doubleAlloc.max_size() << std::endl;
 
	std::cout << std::endl;
 
	std::allocator<std::string> stringAlloc;
	std::cout << "stringAlloc.max_size(): " << stringAlloc.max_size() << std::endl;
 
	std::string* myString = stringAlloc.allocate(3);
 
	stringAlloc.construct(myString, "Hello");
	stringAlloc.construct(myString + 1, "World");
	stringAlloc.construct(myString + 2, "!");
 
	std::cout << myString[0] << " " << myString[1] << " " << myString[2] << std::endl;
 
	stringAlloc.destroy(myString);
	stringAlloc.destroy(myString + 1);
	stringAlloc.destroy(myString + 2);
	stringAlloc.deallocate(myString, 3);
 
	std::cout << std::endl;
 
	return 0;
}
 
//
// reference: http://en.cppreference.com/w/cpp/memory/allocator
int test_allocator_4()
{
	std::allocator<int> a1;   // default allocator for ints
	int* a = a1.allocate(1);  // space for one int
	a1.construct(a, 7);       // construct the int
	std::cout << a[0] << '\n';
	a1.deallocate(a, 1);      // deallocate space for one int
 
	// default allocator for strings
	std::allocator<std::string> a2;
 
	// same, but obtained by rebinding from the type of a1
	decltype(a1)::rebind<std::string>::other a2_1;
 
	// same, but obtained by rebinding from the type of a1 via allocator_traits
	std::allocator_traits<decltype(a1)>::rebind_alloc<std::string> a2_2;
 
	std::string* s = a2.allocate(2); // space for 2 strings
 
	a2.construct(s, "foo");
	a2.construct(s + 1, "bar");
 
	std::cout << s[0] << ' ' << s[1] << '\n';
 
	a2.destroy(s);
	a2.destroy(s + 1);
	a2.deallocate(s, 2);
 
	return 0;
}
 
} // namespace allocator_

GitHub: https://github.com/fengbingchun/Messy_Test 

到此這篇關(guān)于C++中std::allocator的使用案例詳解的文章就介紹到這了,更多相關(guān)C++中std::allocator的使用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C語言中十六進制轉(zhuǎn)十進制兩種實現(xiàn)方法

    C語言中十六進制轉(zhuǎn)十進制兩種實現(xiàn)方法

    這篇文章主要介紹了C語言中十六進制轉(zhuǎn)十進制兩種實現(xiàn)方法的相關(guān)資料,需要的朋友可以參考下
    2017-01-01
  • 深入解析C++編程中__alignof 與__uuidof運算符的使用

    深入解析C++編程中__alignof 與__uuidof運算符的使用

    這篇文章主要介紹了C++編程中__alignof 與__uuidof運算符的使用,是C++入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下
    2016-01-01
  • C++實現(xiàn)LeetCode(5.最長回文子串)

    C++實現(xiàn)LeetCode(5.最長回文子串)

    這篇文章主要介紹了C++實現(xiàn)LeetCode(5.最長回文子串),本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • Cocos2d-x中使用CCScrollView來實現(xiàn)關(guān)卡選擇實例

    Cocos2d-x中使用CCScrollView來實現(xiàn)關(guān)卡選擇實例

    這篇文章主要介紹了Cocos2d-x中使用CCScrollView來實現(xiàn)關(guān)卡的選擇實例,本文在代碼中用大量注釋講解了CCScrollView的使用,需要的朋友可以參考下
    2014-09-09
  • 用C++實現(xiàn)一個命令行進度條的示例代碼

    用C++實現(xiàn)一個命令行進度條的示例代碼

    這篇文章主要介紹了用C++實現(xiàn)一個命令行進度條的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-04-04
  • c語言數(shù)據(jù)結(jié)構(gòu)之棧和隊列詳解(Stack&Queue)

    c語言數(shù)據(jù)結(jié)構(gòu)之棧和隊列詳解(Stack&Queue)

    這篇文章主要介紹了c語言數(shù)據(jù)結(jié)構(gòu)之棧和隊列詳解(Stack&Queue),文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-08-08
  • C/C++惡意代碼盤點之文件自動刪除

    C/C++惡意代碼盤點之文件自動刪除

    惡意代碼的分類包括計算機病毒、蠕蟲、木馬等,有些技術(shù)經(jīng)常用到,有的也是必然用到。今天我們就分享一下文件自動刪除,感興趣的可以了解一下
    2022-09-09
  • C語言文件操作函數(shù)freopen詳細解析

    C語言文件操作函數(shù)freopen詳細解析

    替換一個流,或者說重新分配文件指針,實現(xiàn)重定向。如果stream流已經(jīng)打開,則先關(guān)閉該流。如果該流已經(jīng)定向,則freopen將會清除該定向。此函數(shù)一般用于將一個指定的文件打開一個預(yù)定義的流:標準輸入、標準輸出或者標準出錯
    2013-10-10
  • 一文詳解C++模板和泛型編程

    一文詳解C++模板和泛型編程

    這篇文章主要為為大家為大家詳細的介紹了C++模板和泛型編程使用,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-05-05
  • C++中的運算符重載詳解

    C++中的運算符重載詳解

    大家好,本篇文章主要講的是C++中的運算符重載詳解,感興趣的同學(xué)趕快來看一看吧,對你有幫助的話記得收藏一下
    2022-01-01

最新評論

石首市| 明水县| 海阳市| 班戈县| 奇台县| 成都市| 宁明县| 兴隆县| 朝阳区| 旅游| 镇坪县| 台中县| 紫金县| 五大连池市| 上林县| 澎湖县| 玉溪市| 斗六市| 邳州市| 筠连县| 清远市| 井研县| 内丘县| 东兰县| 年辖:市辖区| 凤山市| 马公市| 中宁县| 宝鸡市| 云阳县| 高要市| 酒泉市| 贵州省| 简阳市| 中牟县| 张北县| 新民市| 黎平县| 娄烦县| 孝感市| 准格尔旗|