C++內存管理(候捷)第一講 筆記

內存分配的每一層面

在這里插入圖片描述
applications可以調用STL,里面會有allocator進行內存分配;也可以使用C++ 基本工具primitives,比如new, new[], new(), ::operator new();還可以使用更底層的malloc和free分配和釋放內存。最底層的是系統調用,比如HeapAlloc,VirtualAlloc
在這里插入圖片描述
在C中,malloc 和 free 是標準庫函數,不涉及構造函數和析構函數,只是簡單的內存分配和釋放

int *ptr = (int *)malloc(sizeof(int));
free(ptr);

在C++中,new 和 delete 不僅僅是內存分配和釋放的操作符,還會處理對象的構造和析構

四個層面的基本用法

在這里插入圖片描述
malloc和 ::operator new()是完全一樣的效果
allocator()是創建一個臨時對象來調用非static函數
在這里插入圖片描述
__GNUC__版本4.9的分配器

基本構件之一new delete expression上

在這里插入圖片描述
由于有分配內存,因此要try catch考慮內存分配失敗時如何處理
new的過程:1.分配內存 2.指針轉型 3.調用構造函數

在指定內存上創建對象使用placement new:new (pointer) Type(initializer);

void* memory = operator new(sizeof(MyClass)); // 分配內存
MyClass* obj = new (memory) MyClass(/* constructor arguments */); // 在指定內存位置創建對象
void* memory = operator new[](sizeof(MyClass) * 5); // 分配數組內存
MyClass* objArray = new (memory) MyClass[5]; // 在數組內存中創建對象

_callnewh 不是 C++ 標準中的函數,而是可能是用戶定義的一個函數。通常情況下,這類函數的名字以 _new_handler 結尾,用于處理內存分配失敗的情況。
在 C++ 中,當 new 表達式無法分配所需的內存時,會調用用戶指定的 new_handler 函數。new_handler 是一個函數指針,指向一個用戶定義的函數,其原型通常為

typedef void (*new_handler)();

這個函數可以嘗試釋放內存、擴大內存池,或者執行其他操作來嘗試解決內存不足的問題。如果 new_handler 能夠成功處理內存不足的情況,返回;如果不能處理,可以選擇拋出異常或者終止程序

基本構件之一new delete expression中

在這里插入圖片描述
使用定位 new 運算符后,必須手動調用對象的析構函數來釋放資源,否則可能導致內存泄漏

obj->~MyClass(); // 手動調用析構函數
operator delete(memory); // 手動釋放內存

delete的動作:先調用析構函數,然后釋放內存。
operator delete里調用free

基本構件之一new delete expression下

在這里插入圖片描述
ctor和dtor直接調用的測試

Array new

在這里插入圖片描述
cookie記錄的是下面一塊的長度。malloc分配的時候會額外帶上一塊cookie的信息,供給free釋放
在這里插入圖片描述
測試
在這里插入圖片描述
vc6下malloc new int[10]內存布局:灰色表示具體數據,橙色是debug模式下添加的內存。上面和最下面的兩個0x61(61H)是cookie,記錄整體內存分配的大小。61H實際上是60H,表示內存分配的大小,后面1H意思是占用最后一位,表示內存分配出去。淺藍色的pad表示補齊,填補到16的倍數
在這里插入圖片描述
在這里插入圖片描述

placement new

在這里插入圖片描述
placement new允許我們將對象建構在已經分配好的內存中

Complex* pc = new(buf)Complex(1, 2);這句話會被編譯器轉換為,分別調用operator new(需要第二個參數,表示位置,這個函數只是傳回這個位置,不再分配內存),指針轉型,調用構造函數

重載

在這里插入圖片描述
new是表達式,不可改變不可重載。會調用 operator new,全局(可重載但少見)或者成員函數(可重載)
在這里插入圖片描述
容器里把構造函數和析構函數包裝在 construct()和destroy(),內存分配動作allocate()和deallocate()會走入分配器allocator中處理

容器分配內存的一般途徑:容器使用分配器,在這里插入圖片描述
分配器調用 ::operator new 和 ::operator delete,底層可能調用 malloc 和 free:
在這里插入圖片描述
重載全局的::operator new 和::operator delete
在這里插入圖片描述
在一個類中重載operator new和operator delete。編譯器會自動調用
通常會加static,因為調用的地方通常在創建對象的過程中,無法通過對象來調用一般函數
在這里插入圖片描述

重載示例

在這里插入圖片描述
在這里插入圖片描述
重載示例
有虛函數只是把大小放大了,一個12,一個16
在GNU C++4.9版本中構造是從上到下,析構是從下到上
在這里插入圖片描述
使用全局new,delete示例
在這里插入圖片描述
placement new的重載第一參數必須是size_t類型,接受類的大小,會傳入Foo的大小。其余的參數就是括號里的參數
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
平常使用的string,就是個typedef ,define basic_string。重載了operator new。每次創建時也額外分配字符串大小的內存

Per class allocator

在這里插入圖片描述
內存池:用malloc分配一大塊(內存池),然后分成小塊,減少malloc的調用次數。另外減少cookie的用量。
在Screen類中引入一個指針next,它的大小是4B,用于串聯鏈表
delete操作,把指針p回收到單向鏈表中,放到鏈表的頭指針位置
在這里插入圖片描述
左邊間隔8表示每個Screen對象內存分配的大小為8B,說明每個Screen分配的時候沒有cookie。
右邊間隔16,表示每個Screen對象內存分配的大小為16B,這是因為對象分配的時候上下加了cookie,最上面和最下面的cookie大小共為8B

Per class allocator 2

在這里插入圖片描述
struct AirplaneRep,由于對齊,5B會變成8B
union 是一種特殊的數據結構,可以看作同一個東西,用不同的名稱/不同的角度去看待。
上述例子用指針去看待union時,只看8個字節的前4個字節

通過union借用內存塊的前4個字節當作指針
在這里插入圖片描述
delete沒有free,只是把區塊回收到鏈表,并未把內存還給操作系統,鏈表可能會越來越長,超過512塊

Static allocator

從軟件工程的角度看,上面的operator new和operator delete對于不同 類都要重載,明顯不是一個好的解法,因此將allocator抽象成一個類。

具體的類進行內存分配的時候,只需要調用allocator即可
在這里插入圖片描述
在這里插入圖片描述
嵌入式指針embedded pointer:借用A對象所占用的內存空間中的前4個字節,這4個字節用來 鏈住這些空閑的內存塊;但是,一旦某一塊被分配出去,那么這個塊的 前4個字節 就不再需要。因此類A對象的sizeof必須不小于4字節

上述例子定義一個類型obj,不放在外部,污染全局變量。struct里放了一個指針,它的大小為4個字節。這個指針的值,存著下一個內存的地址。由于這里只需要指針,所以union可以不使用。
在這里插入圖片描述
由于上面的CHUNK設置為5,每5個對象的內存空間是連續的(間隔都是一個對象的大小),而每個大塊之間是不連續的。

Macro for static allocator

在這里插入圖片描述
把allocator的部分拿出來用宏來定義
宏是預處理指令,用于在編譯過程中執行文本替換。宏通常通過 #define 關鍵字定義,并在代碼中通過宏名稱來調用。它們是一種簡單的文本替換機制,可以用于創建常量、函數替代、條件編譯等。
在宏定義的末尾使用反斜杠是為了告訴編譯器該宏定義將在下一行繼續。如果在宏定義的最后一行沒有使用反斜杠,那么編譯器會認為宏定義結束了

版本1:指針,版本2:embedded pointer,版本3:抽取內存的動作到單一class Allocator 版本4:alloctator通過宏抽取出來
在這里插入圖片描述
標準庫中的allocator
其中一種分配器有16條自由鏈表,來應對不同大小的塊分配,不同的大小的類對象,分配到不同的鏈表中

New Handler

在這里插入圖片描述
new handler 是一個函數指針,當 new 操作符無法分配所需的內存時,會調用與之關聯的 new handler
new handler 是全局的,一旦設置,會在程序的生命周期內一直有效,直到被其他 set_new_handler 覆蓋
在這里插入圖片描述
new handler的例子
在這里插入圖片描述
在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/40742.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/40742.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/40742.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

實現好友關注功能的Feed流設計

摘要 在社交網絡應用中,Feed流是展示好友動態的核心功能。本文將探討如何設計一個Feed流系統,以實現好友關注和動態展示的功能。 1. Feed流的基本概念 Feed流是用戶在社交網絡中獲取信息的一種方式,通常按照時間順序展示好友或感興趣的用戶…

Maven Archetype 自定義項目模板:高效開發的最佳實踐

文章目錄 前言一、Maven Archetype二、創建自定義 Maven Archetype三、定制 Archetype 模板四、手動創建 Archetype 模板項目五、FAQ5.1 如何刪除自定義的模板5.2 是否可以在模板中使用空文件夾 六、小結推薦閱讀 前言 在軟件開發中,標準化和快速初始化項目結構能夠…

調用asyncio.to_thread后上下文依然一致嗎

使用Python的asyncio時,可以把一個同步的函數放到線程池中執行從而避免這個函數阻塞asyncio自身的事件循環。比如可以把requests庫的請求放進去 async def to_thread_do_request(url):return await asyncio.to_thread(requests.get, url)這個to_thread_do_request方…

14-20 Vision Transformer用AI的畫筆描繪新世界

概述 毫無疑問,目前最受關注且不斷發展的最重要的主題之一是使用人工智能生成圖像、視頻和文本。大型語言模型 (LLM) 已展示出其在文本生成方面的卓越能力。它們在文本生成方面的許多問題已得到解決。然而,LLM 面臨的一個主要挑戰是它們有時會產生幻覺反應。 最近推出的新模…

分布式計算、異構計算與算力共享

目錄 算力 算力共享的技術支撐 云計算技術 邊緣計算技術 區塊鏈技術 分布式計算、異構計算與算力共享 分布式計算:計算力的“集團軍作戰” 異構計算:計算力的“多兵種協同” 算力共享:計算力的“共享經濟” 深入融合,共創計算新紀元 算力共享對科研領域的影響 …

openmetadata1.3.1 自定義連接器 開發教程

openmetadata自定義連接器開發教程 一、開發通用自定義連接器教程 官網教程鏈接: 1.https://docs.open-metadata.org/v1.3.x/connectors/custom-connectors 2.https://github.com/open-metadata/openmetadata-demo/tree/main/custom-connector (一&…

Matplotlib 文本

可以使用 xlabel、ylabel、text向圖中添加文本 mu, sigma 100, 15 x mu sigma * np.random.randn(10000)# the histogram of the data n, bins, patches plt.hist(x, 50, densityTrue, facecolorg, alpha0.75)plt.xlabel(Smarts) plt.ylabel(Probability) plt.title(Histo…

Qt讀取ini格式配置文件的類設計

目錄 1.引言 2.QSettings 2.1.功能特點 2.2.基本用法 3.讀取ini文件配置通用類設計 3.1.設計要點 3.2.完整實現 3.3.調用方法 4.總結 1.引言 在編寫應用程序的時,有些參數需要用戶配置,那么這些參數就涉及到存儲了,單從存儲來講&…

git 還原被刪除的分支

在多人項目開發中,有一次碰到忘記合并到master分支了,直接就把開發分支給刪除了,現在記錄下怎么還原被刪除的分支 必須保證刪除的分支之前已經被推送到了遠程倉庫 # 找出被刪除分支的最后一個提交的哈希值 git reflog show# 找到提交哈希值…

2024/07/04

1、梳理筆記(原創) 2、終端輸入一個日期&#xff0c;判斷是這一年的第幾天 scanf("%d-%d-%d",&y,&m,&d); 閏年2月29天&#xff0c;平年2月28天 #include<stdio.h> int main(int argc, char const *argv[]) {int y0,m0,d0;printf("please ente…

析構函數和拷貝構造函數

文章目錄 析構函數1.析構函數的定義&#xff1a;2.析構函數的語法&#xff1a;3.析構函數的特性&#xff1a; 拷貝構造函數1.拷貝構造函數的定義&#xff1a;2.拷貝構造函數的語法3.拷貝構造函數的特性(1)拷貝構造函數是構造函數的一個重載形式**(這個其實也很好理解&#xff0…

鴻蒙開發設備管理:【@ohos.thermal (熱管理)】

熱管理 該模塊提供熱管理相關的接口&#xff0c;包括熱檔位查詢及注冊回調等功能。 說明&#xff1a; 本模塊首批接口從API version 8開始支持。后續版本的新增接口&#xff0c;采用上角標單獨標記接口的起始版本。開發前請熟悉鴻蒙開發指導文檔&#xff1a;gitee.com/li-shi…

如何實現圖片垂直旋轉90度的問題

非常簡單的問題&#xff0c;一串代碼就可以解決。復制修改一下就可以直接使用&#xff0c;一個簡單的小demo。寫項目的時候需要寫的功能&#xff0c;不到二十行代碼就可以實現。 <html> <head><title>旋轉圖片</title><meta http-equiv"Conte…

Land survey boundary report (template)

Land survey boundary report (template) 土地勘測定界報告&#xff08;模板&#xff09;.doc

【高校科研前沿】南京地理與湖泊研究所博士后夏凡為第一作者在環境科學與水資源領域Top期刊發文:鈣對云南洱海溶解有機質與浮游細菌相互作用的調控作用

文章簡介 論文名稱&#xff1a;Calcium regulates the interactions between dissolved organic matter and planktonic bacteria in Erhai Lake, Yunnan Province, China 第一作者及單位&#xff1a;夏凡&#xff08;博士后|中國科學院南京地理與湖泊研究所&#xff09; 通訊…

Git指令

一 參考&#xff1a;https://zhuanlan.zhihu.com/p/389814854 1.clone遠程倉庫 git clone https://git.xiaojukeji.com/falcon-mg/dagger.git 2.增加當前子目錄下所有更改過的文件至index git add . 3.提交并備注‘xxx’ git commit -m ‘xxx’ 4.顯示本地分支 git branch 5.顯…

【pytorch13】激活函數及梯度

什么是激活函數 計算機科學家借鑒生物的神經元機制發明了計算機上的模型&#xff0c;這個模型與生物的神經元非常類似 激活的意思就是z變量要大于0&#xff0c;這一個節點才會激活&#xff0c;否則就會處于睡眠狀態不會輸出電平值 該激活函數在z0處不可導&#xff0c;因此不能…

Asp .Net Core 系列:基于 Castle DynamicProxy + Autofac 實踐 AOP 以及實現事務、用戶填充功能

文章目錄 什么是 AOP &#xff1f;.Net Core 中 有哪些 AOP 框架&#xff1f;基于 Castle DynamicProxy 實現 AOPIOC中使用 Castle DynamicProxy實現事務管理實現用戶自動填充 什么是 AOP &#xff1f; AOP&#xff08;Aspect-Oriented Programming&#xff0c;面向切面編程&a…

OpenCV——把YOLO格式的圖片目標截圖,并按目標類別保存

import os import cv2def get_class_folder(catagetory,class_id, base_folder):# 根據類別ID創建文件夾路徑class_folder os.path.join(base_folder, catagetory[int(class_id)])if not os.path.exists(class_folder):os.makedirs(class_folder)return class_folderdef crop_…

VPN是什么?

VPN&#xff0c;全稱Virtual Private Network&#xff0c;即“虛擬私人網絡”&#xff0c;是一種在公共網絡&#xff08;如互聯網&#xff09;上建立加密、安全的連接通道的技術。簡單來說&#xff0c;VPN就像是一條在公共道路上鋪設的“秘密隧道”&#xff0c;通過這條隧道傳輸…