中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

C++內存管理工具primitives怎么用

發布時間:2022-09-23 15:14:00 來源:億速云 閱讀:113 作者:iii 欄目:開發技術

本篇內容主要講解“C++內存管理工具primitives怎么用”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“C++內存管理工具primitives怎么用”吧!

primitives

C++內存管理工具primitives怎么用

分配釋放屬于是否可重載
malloc()free()C不可
newdeleteC++表達式不可
::operator new()::operator delete()C++函數
allocator::allocate()allocator::deallocate()C++標準庫可自由設計搭配容器

new 和 delete

C/C++中的new和delete的實現過程

C++內存管理工具primitives怎么用

operator new():第一個參數表示大小,第二個參數表示保證這個函數不拋出異常。

C++內存管理工具primitives怎么用

注意:構造函數不能直接調用,而析構函數可以直接調用。

new[] 與 delete[] 要搭配使用,未搭配使用可能會內存泄漏,泄露的是指針所指向的地方。

析構的時候次序會逆反。

C++內存管理工具primitives怎么用

對于 析構函數 沒有意義,new[] 是否對應 delete[] 不重要,但是 當析構函數有意義時,必須對應。

placement new

placement new 允許我們將對象建構在一個已經分配的內存中。并且沒有對應的placement delete。

C++內存管理工具primitives怎么用

第一部分,本來是分配內存,現在已經分配好了,所以直接返回。

重載 operator new

::operator new 和::operator delete 全部可以重載,但是不推薦。類中 operator new 也可以重載,實現所需功能,這是最常用的。

class Foo{
public:
	void *operator new(size_t);
	void operator delete(void*,size_t);
	//....
};

注意,可以寫出多個版本,前提是每一個版本的聲明都必須有獨特的參數列。(第一參數必須是size_t)只有new所調用的ctor 拋出異常,才會調用這些重載版的 operator delete()。

即使 operator delete() 未能一一對應operator new() 也不會出現任何報錯。換句話說:放棄處理構造函數拋出的異常。

per-class allocator

一:

C++內存管理工具primitives怎么用

想利用類內重載operator new去接管內存的分配,然后利用內存池的觀念【即創建出一大段連續空間的內存,然后將其切割成一小段一小段】,將創建的元素對象放在內存池切分好的各分段小內存片中,這樣避免了多次調用new而造成生成多個帶有cookie的內存空間。通過內存池的觀念,可以生成一大段只帶有兩個頭尾cookie的內存空間,而該一大段內存空間又被切分成每一小段的內存空間,且其中的每一小段內存空間片都可以共享這一整體的cookie信息。

因為為了能將一大段內存空間切分成一小段一小段,然后通過單向鏈表的形式串接起來,所以必須多引入一個Screen* next指針。但這又會增加class Screen的大小【增加了4字節】。

二:第一個占用了一個指針,浪費空間

C++內存管理工具primitives怎么用

這個版本通過union關鍵字來減少使用next而所占耗的內存!

注意:上面兩個版本的operator delete操作都沒有將內存空間回收還回給系統,而是仍然存在的。雖然operator delete操作沒有將這些分配的內存空間釋放掉,但其仍在控制中即仍可繼續重新使用【只不過freeStore或headOfFreeList此時又重新跑回整個一大塊內存空間的頭端】,所以不算內存泄漏!

三:上面的版本不具有復用性

將分配特定尺寸區塊的memory allocator包裝成一個class allocator,這樣每個allocator object都是個分配器,體內維護一個free lists,不同類(如下面的class Foo,class Goo等) 里面調用生成的各自allocator objects維護不同的free lists。

C++內存管理工具primitives怎么用

由上知,class Foo或class Goo其operator new或operator delete最終調用的都是allocator object所維護的free list而進行操作的!

另外,class Foo或class Goo中,應注意到:

static allocator myAlloc,即myAlloc必須是個靜態成員變量,且在類外定義(賦初值)。如果其不是靜態成員變量時,則在構建class Foo類對象時,是沒辦法調用到myAlloc的。因為非靜態成員變量只能通過對象調用【但此時Foo對象還沒生成又如何調用!!】。而myAlloc又是用來生成Foo類對象的,所以得通過類名調用即應設置為static類型。

C++內存管理工具primitives怎么用

而class allocator的如下:

class allocator{
private:
	struct obj{
		struct obj* next;
	};
public:
	static void* allocate(size_t);
	static void deallocate(void*, size_t);
private:
	obj* freeStore = nullptr;
	const int CHUNK = 5; // 標準庫一般設置為20
};
void* allocator::allocate(size_t size){
	obj* p;
	if(!freeStore){
		// linked list為空,則申請一大塊
		size_t chunk = CHUNK * size;
		freeStore = p =(obj*)malloc(chunk); // 這里直接調用malloc進行分配空間
		// 將分配的一大塊切分成5小段,并串接起來
		for(int i = 0; i < (CHUNK - 1); ++i){
			p->next = (obj*)((char*)p + size);
			p = p->next;
			// 上面這兩步相當于p->next = p + 1,
			// 只不過這里需要適應不同的類下的操作,因而設置成這種形式!!
		}
		p->next = nullptr; // 最后一小段的下一個位置指向空
	}
	p = freeStore;
	freeStore = freeStore->next;
	return p;
}
void allocator::deallocate(void* p, size_t){
	// 將要刪除的*p的位置調整為free list的頭端
	((obj*)p)->next = freeStore;
	freeStore = (obj*)p;
}

四、macro for static allocator(per-class allocator 4)

C++內存管理工具primitives怎么用

由第三版本知,其黃色部分我們想將其定義為宏操作,進一步簡化代碼內容:

// DECLARE_POOL_ALLOC  used in class definition
#define DECLARE_POOL_ALLOC()\
public:\
    void* operator new(size_t size){
        return myAlloc.cllocate(size);
    }\
    void operator delete(void* p){
        myAlloc.deallocate(p, 0);
    }\
protected:\
    static allocator myAlloc;

// IMPLEMENT_POOL_ALLOC   used in class implementation file
#define IMPLEMENT_POOL_ALLOC(class_name)\
    allocator class_name::myAlloc;

使用實例如圖所示:

C++內存管理工具primitives怎么用

在類內進行宏聲明,在類外進行宏定義【告訴編譯器傳入參數的class type】

New Handler

C++內存管理工具primitives怎么用

C++內存管理工具primitives怎么用

=default,=delete

一個是需要默認版本,另一個是這個函數我不要。

這兩個函數不僅使用構造,同時適用于 operator new 和 operator delete。

C++內存管理工具primitives怎么用

到此,相信大家對“C++內存管理工具primitives怎么用”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

济南市| 巴南区| 米林县| 湾仔区| 呼玛县| 墨江| 孟州市| 顺昌县| 尼勒克县| 菏泽市| 凉山| 萝北县| 九龙坡区| 东乡| 游戏| 平陆县| 庐江县| 南召县| 惠东县| 宁远县| 桃源县| 临颍县| 建瓯市| 桦川县| 呼和浩特市| 阳谷县| 廊坊市| 昌江| 色达县| 商丘市| 健康| 绥宁县| 本溪市| 石棉县| 鸡泽县| 海口市| 闻喜县| 九江市| 三原县| 襄垣县| 吉安县|