您好,登錄后才能下訂單哦!
這篇文章主要講解了“C++內存管理的知識點有哪些”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“C++內存管理的知識點有哪些”吧!
在C++中,內存可以分為 5 個區,分別為棧,堆,自由存儲區,全局/靜態變量,常量存儲區。
(1)棧:在執行函數時,函數內局部變量的存儲單元在棧上創建,函數執行完時這些存儲單元被自動釋放。
(2)堆:通過 malloc 分配的內存塊,通常和 free 搭配,需要手動釋放。
(3)自由存儲區:通過 new 分配的內存塊,通常和 delete 搭配,也需要手動釋放。
(4)全局/靜態存儲區:用于存儲全局變量和靜態變量。
(5)常量存儲區:用于存放常量,不允許修改。
(1)空間分配不同:棧存放函數內的局部變量,由操作系統自動釋放;堆通過 malloc 分配,需要手動釋放。
(2)緩存方式不同:棧使用的是一級緩存,被調用時處于存儲空間;堆使用的是二級緩存,速度要慢些。
(3)數據結構不同:棧類似棧結構,先進后出;堆類似數組結構,先進先出。
malloc 分配在堆中,他會分配一塊指定大小的內存空間,并返回一個指針,使用完畢后需要手動回收。
局部變量分配在在棧中,超過作用域后系統自動回收。
(1)數據段:存放程序中已初始化的全局變量和靜態變量。
(2)代碼段:存放程序執行代碼的一塊區域,頭部包含一些常數變量。
(3)BSS段:存放程序中未初始化的全局變量和靜態變量的一塊區域。
(4)可執行程序在運行時會多出兩個區域:
堆:動態申請內存用。從低向高增長。
棧:存儲局部變量,函數參數值。從高向低增長。
(5)在堆和棧之間有個文件映射區。
(1)操作系統創建相應的進程并分配進程空間,加載器把可執行文件中的代碼段,數據段映射到進程中的虛擬空間。
(2)加載器讀入可執行程序中的導入符號表,根據符號表可以查詢需依賴的動態依賴庫。
(3)加載器將程序中的動態依賴庫進行導入。
(4)初始化應用程序中的全局變量,對于全局變量自動調用構造函數。
(5)進入程序入口函數開始執行。
數據區:存放初始化不為 0 的全局變量和靜態變量。
BSS區:存放初始化為 0 或未初始化的全局變量和靜態變量。
內存泄漏:
申請了一塊兒內存空間,但是使用完畢后沒有釋放。
(1)new 和 malloc 申請后,沒有使用 delete 和 free 釋放。
(2)子類繼承父類時,父類析構函數不是虛函數。
(3)windows 句柄資源使用后沒有釋放。
對策:
(1)養成良好的編程習慣,分配的內配使用后,記的釋放。
(2)將分配內存的指針以鏈表的形式存儲,使用完畢后從鏈表中刪除進行管理。
(3)使用智能指針。
常見內存錯誤:
(1)內存分配未成功卻使用。
(2)內存分配成功,但是未初始化就引用。
(3)內存分配成功并初始化,但是操作超出了內存的邊界。
(4)忘記了釋放內存,造成內存泄漏。
(5)釋放了內存卻繼續使用。
對策:
(1)用 malloc 或 new 申請內存后,應該檢查返回的指針是否為 NULL。
(2)為指針初始化為 NULL,為數組和動態內存賦初值。
(3)避免數組越界。
(4)動態內存的申請和釋放必須配對。
(5)用 free 和 delete 釋放內存之后,指針應該置空防止野指針。
(6)使用智能指針。
為了能夠使 CPU 進行快速的訪問,變量的起始地址應該具有某些特征,即對齊。比如 4 字節的 int,起始地址應該在 4 字節的邊界上。
假如變量的地址不是自然對齊,那么 CPU 要訪問該值的話需要訪問兩次或三次內存,而對齊的話只需要一次,訪問的速度更快。
內存對齊一般應用在 struct,class,union 數據類型中。
感謝各位的閱讀,以上就是“C++內存管理的知識點有哪些”的內容了,經過本文的學習后,相信大家對C++內存管理的知識點有哪些這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。