C++| 深入剖析std::list底層實現:鏈表結構與內存管理機制

引言

std::list的底層實現基于雙向鏈表,其設計哲學與std::vector截然不同。本文將深入探討其節點結構、內存分配策略及迭代器實現原理,揭示鏈表的性能優勢和潛在代價。


1. 底層數據結構:雙向鏈表

每個std::list節點包含:

  • 數據域:存儲元素值。

  • 前驅指針prev):指向前一個節點。

  • 后繼指針next):指向后一個節點。

鏈表示例

struct _List_node {_List_node* _M_prev;_List_node* _M_next;_Tp _M_data;
};

2. 內存分配機制
2.1 節點動態分配
  • 每次插入元素時,從內存池(通過分配器)申請一個節點內存。

  • 刪除元素時,立即釋放節點內存,無內存預留機制。

2.2 分配器(Allocator)

默認使用std::allocator,但允許自定義分配器優化高頻操作:

// GCC中list的模板定義
template<typename _Tp, typename _Alloc = std::allocator<_Tp>>
class list {typedef _List_node<_Tp> _Node;_Node* _M_node; // 指向哨兵節點(end()位置)
};

3. 迭代器實現
3.1 迭代器結構

std::list的迭代器為雙向迭代器(非隨機訪問),內部封裝節點指針:

template<typename _Tp>
struct _List_iterator {_List_node<_Tp>* _M_node;// 前置++_List_iterator& operator++() { _M_node = _M_node->_M_next;return *this;}// 解引用_Tp& operator*() { return _M_node->_M_data; }
};
3.2 迭代器穩定性
  • 插入操作:迭代器永不失效(新節點不影響現有節點指針)。

  • 刪除操作:僅被刪除元素的迭代器失效,其他迭代器仍有效。


4. 關鍵操作源碼解析(以GCC為例)
4.1 插入操作
// 在position前插入值為__x的節點
template<typename _Tp>
void list<_Tp>::insert(iterator __position, const _Tp& __x) {_Node* __tmp = _M_create_node(__x); // 創建新節點__tmp->_M_next = __position._M_node;__tmp->_M_prev = __position._M_node->_M_prev;__position._M_node->_M_prev->_M_next = __tmp;__position._M_node->_M_prev = __tmp;
}
4.2 刪除操作
// 刪除position處的節點
template<typename _Tp>
void list<_Tp>::erase(iterator __position) {_Node* __next = __position._M_node->_M_next;_Node* __prev = __position._M_node->_M_prev;__prev->_M_next = __next;__next->_M_prev = __prev;_M_put_node(__position._M_node); // 釋放節點內存
}

5. 性能與局限性
5.1 時間復雜度
  • 插入/刪除:O(1)(但需注意查找位置的O(n)開銷)。

  • 訪問元素:O(n)。

5.2 內存碎片問題
  • 頻繁增刪節點可能導致內存碎片,降低內存訪問效率。

  • 解決方案:預分配節點池(需自定義分配器)。


6. 對比其他容器
特性std::liststd::vectorstd::deque
內存布局非連續連續分塊連續
中間插入/刪除O(1)O(n)O(n)
隨機訪問不支持O(1)O(1)
迭代器失效僅刪除時局部失效擴容時全體失效中間修改時可能失效

結語

std::list通過雙向鏈表實現了極致的插入刪除性能,但其非連續內存的特性也帶來了訪問效率的妥協。理解其底層機制有助于在內存敏感或高頻修改的場景中發揮其優勢,同時規避潛在的性能陷阱。

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

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

相關文章

漢諾塔問題——用貪心算法解決

目錄 一&#xff1a;起源 二&#xff1a;問題描述 三&#xff1a;規律 三&#xff1a;解決方案 遞歸算法 四&#xff1a;代碼實現 復雜度分析 一&#xff1a;起源 漢諾塔&#xff08;Tower of Hanoi&#xff09;問題起源于一個印度的古老傳說。在世界中心貝拿勒斯&#…

【Python】Python 100題 分類入門練習題 - 新手友好

Python 100題 分類入門練習題 - 新手友好篇 - 整合篇 一、數學問題題目1&#xff1a;組合數字題目2&#xff1a;利潤計算題目3&#xff1a;完全平方數題目4&#xff1a;日期天數計算題目11&#xff1a;兔子繁殖問題題目18&#xff1a;數列求和題目19&#xff1a;完數判斷題目21…

【linux】--- 進程概念

進程概念 1.認識馮諾依曼結構2. 操作系統&#xff08;Operator system)2.1 概念2.2 設計OS的目的2.3 理解操作系統2.4 如何理解管理2.5 理解系統調用和庫函數 3. 進程3.1 基本概念和基本操作3.1.1 描述進程 - PCB3.1.2 task_struct3.1.3 查看進程 3.2 進程狀態3.2.1 運行&&…

算法堆排序記錄

【算法】排序算法之堆排序 - 知乎 應用場景&#xff1a;獲取第n個大或者小的數 操作步驟&#xff1a; 1、將數組構造成堆 2、調整根節點為最大堆 ->倒序對每個根節點執行最大化 ->根節點最大化過程中如果發生交換&#xff0c;需要保證子節點也為最大堆&#xff08;執行…

STM32 模塊化開發實戰指南:系列介紹

本文是《STM32 模塊化開發實戰指南》系列的導讀篇,旨在介紹整個系列的寫作目的、適用讀者、技術路徑和每一篇的主題規劃。適合從事 STM32、裸機或 RTOS 嵌入式開發的個人開發者、初創工程師或企業項目團隊。 為什么要寫這個系列? 在嵌入式開發中,很多人剛開始都是從點亮一個…

【眼底輔助診斷開放平臺】項目筆記

這是一個標題 任務一前端頁面開發&#xff1a;后端接口配置&#xff1a; 任務二自行部署接入服務 日志修改樣式和解析MD文檔接入服務 Note前端登陸不進去/更改后端api接口304 Not Modifiedlogin.cache.jsonERR_CONNECTION_TIMED_OUT跨域一般提交格式proxy.ts src/coponents 目錄…

【后端開發】Spring MVC-計算器、用戶登錄、留言板

文章目錄 前后端分離設計接口設計思路項目問題解決思路 計算器需求分析接口定義前端頁面代碼服務器代碼 用戶登錄需求分析接口定義用戶登錄校驗接口查詢登錄用戶接口 前端頁面代碼用戶登錄校驗查詢登錄用戶 服務器代碼前后端交互 留言版需求分析接口定義獲取全部留言發布留言前…

在Ubuntu-22.04.5中安裝ONLYOFFICE DocSpace(協作空間)【注意:安裝失敗,謹慎參考!】

1. 通過Docker安裝 預計需要下載10G的鏡像。 &#xff08;1&#xff09;下載docspace安裝腳本 curl -fsSL https://download.onlyoffice.com/docspace/docspace-install.sh -o docspace-install.sh &#xff08;2&#xff09;修改docker compose的別名為docker-compose ali…

2025年計算機領域重大技術突破與行業動態綜述

——前沿技術重塑未來&#xff0c;開發者如何把握機遇&#xff1f; 2025年第一季度&#xff0c;全球計算機領域迎來多項里程碑式進展&#xff0c;從量子計算到人工智能&#xff0c;從芯片設計到網絡安全&#xff0c;技術革新與產業融合持續加速。本文梳理近三個月內最具影響力…

一、LLM 大語言模型初窺:起源、概念與核心原理

一、初識大模型 1.1 人工智能演進與大模型興起:從A11.0到A12.0的變遷 AI 1.0時代&#xff08;2012-2022年&#xff09; 感知智能的突破&#xff1a;以卷積神經網絡&#xff08;CNN&#xff09;為核心&#xff0c;AI在圖像識別、語音處理等感知任務中超越人類水平。例如&#…

Redis 分布式鎖+秒殺異步優化

文章目錄 問題思路setnx實現鎖誤刪問題和解決方案Redis Lua腳本問題引出解決方案 setnx實現的問題Redission快速入門redission可重入鎖原理 秒殺優化(異步優化)異步秒殺思路秒殺資格判斷Redis消息隊列 問題 比如我們兩個機器都部署了我們項目&#xff0c;這里nginx使用輪詢的方…

機器學習中的距離度量與優化方法:從曼哈頓距離到梯度下降

目錄 前言一、曼哈頓距離(Manhattan Distance)&#xff1a;二、切比雪夫距離 (Chebyshev Distance)&#xff1a;三、 閔可夫斯基距離(Minkowski Distance)&#xff1a;小結四、余弦距離(Cosine Distance)五、杰卡德距離(Jaccard Distance)六、交叉驗證方法6.1 HoldOut Cross-v…

HTML 嵌入標簽對比:小眾(<embed>、<object>) 與 <iframe> 的優缺點及使用場景和方式

需求背景 在網頁開發中&#xff0c;嵌入外部資源預覽&#xff08;如視頻、PDF、地圖或其他網頁&#xff09;是常見的需求。HTML 提供了多種標簽來實現這一功能&#xff0c;其中 <embed>、<object> 和 <iframe> 是最常用的三種。本文將對比它們的優缺點&…

未來七軸機器人會占據主流?深度解析具身智能方向當前六軸機器人和七軸機器人的區別,七軸力控機器人發展會加快嗎?

六軸機器人和七軸機器人在設計、功能和應用場景上存在明顯區別。六軸機器人是工業機器人的傳統架構&#xff0c;而七軸機器人則在多自由度和靈活性方面進行了增強。 本文將在理解這兩者的區別以及為何六軸機器人仍然是市場主流&#xff0c;從多個方面進行深入解讀六軸和七軸區…

C++基礎精講-07

文章目錄 1. const對象2. 指向對象的指針3. 對象數組4. c中const常見用法總結4.1 修飾常量4.2 修飾指針4.3 修飾函數參數4.4 修飾函數返回值4.5 修飾成員函數4.6 const對象 5. 賦值運算符函數&#xff08;補充&#xff09;5.1 概念5.2 默認賦值運算符函數局限5.3 解決辦法 1. c…

軟件測試之接口測試用例設計

1.接口測試用例設計簡介 我們對系統的需求分析完成之后&#xff0c;即可設計對應的接口測試用例&#xff0c;然后用接口測試用例進行接口測試。接口測試用例的設計也需要用到黑盒測試方法&#xff0c;其與功能測試用例設計的方法類似&#xff0c;接口測試用例設計中還需要增加…

(2)VTK C++開發示例 --- 繪制多面錐體

文章目錄 1. 概述2. CMake鏈接VTK3. main.cpp文件4. 演示效果 更多精彩內容&#x1f449;內容導航 &#x1f448;&#x1f449;VTK開發 &#x1f448; 1. 概述 VTK C開發示例程序&#xff1b; 使用C 和VTK繪制一個多面錐體。 環境說明系統ubuntu22.04、windows11cmake3.22、3.2…

公司內部自建知識共享的方式分類、詳細步驟及表格總結,分為開源(對外公開)和閉源(僅限內部),以及公共(全員可訪問)和內部(特定團隊/項目組)四個維度

以下是公司內部自建知識共享的方式分類、詳細步驟及表格總結&#xff0c;分為開源&#xff08;對外公開&#xff09;和閉源&#xff08;僅限內部&#xff09;&#xff0c;以及公共&#xff08;全員可訪問&#xff09;和內部&#xff08;特定團隊/項目組&#xff09;四個維度&am…

DeepSeek使用001:Word中配置DeepSeek AI的V3和R1模型

文章目錄 Word中配置DeepSeek大模型1、勾選開發工具2、信任中心設置3、添加DeepSeek-V3模型4、獲取API KEY5、添加DeepSeek-R1模型6、新建組7、測試使用 Word中配置DeepSeek大模型 1、勾選開發工具 打開【選項】 選擇【自定義功能區】 2、信任中心設置 打開【信任中心】&…

Spark-SQL核心編程語言

利用IDEA開發spark-SQL 創建spark-SQL測試代碼 自定義函數UDF 自定義聚合函數UDAF 強類型的 Dataset 和弱類型的 DataFrame 都提供了相關的聚合函數&#xff0c; 如 count()&#xff0c; countDistinct()&#xff0c;avg()&#xff0c;max()&#xff0c;min()。除此之外&…