C++ vector,dequeu,list容器中元素的引用失效問題

文章目錄

  • 一、std::list不會產生引用失效問題
  • 二、std::vector中元素引用失效問題
  • 三、std::deque中元素引用失效問題

一、std::list不會產生引用失效問題

在C++中,std::list(雙向鏈表)提供了一種非常靈活的容器類型,其設計使其在插入和刪除元素時不會使其他元素的引用或指針失效。這是因為std::list在內部使用節點來存儲元素,每個節點都包含指向前后節點的指針,因此插入和刪除操作只會影響相鄰節點的指針,而不會影響其他節點。

std::list的引用和指針有效性:

  • 插入元素:插入元素時,只需要調整相鄰節點的指針,而不會重新分配或移動其他節點。因此,現有元素的引用和指針不會失效。
  • 刪除元素:刪除元素時,只需要調整相鄰節點的指針,然后刪除節點本身。其他節點的引用和指針仍然有效。

eg:在std::list中插入和刪除元素后,現有元素的引用和指針仍然有效:

#include <iostream>
#include <list>int main() {std::list<int> myList = {1, 2, 3, 4};// 獲取指向第二個元素的引用和指針auto it = myList.begin();++it; // it指向第二個元素(2)int& ref = *it;std::cout << "Value of ref before insertions: " << ref << std::endl; // 輸出2// 在列表中插入和刪除元素myList.insert(it, 10); // 在第二個元素之前插入10myList.push_back(5);   // 在末尾插入5std::cout << "Value of ref after insertions: " << ref << std::endl; // 輸出2myList.erase(it); // 刪除第二個元素(2)std::cout << "List after deletions: ";for (const auto& value : myList) {std::cout << value << " ";}std::cout << std::endl;return 0;
}

測試:

Program returned: 0
Program stdout
Value of ref before insertions: 2
Value of ref after insertions: 2
List after deletions: 1 10 3 4 5 

在這個示例中,即使在列表中插入和刪除元素后,ref(原本指向第二個元素的引用)仍然有效,并且保持其值為2。

使用智能指針避免同樣會導致引用失效問題

  • 使用智能指針(如std::shared_ptr和std::unique_ptr)可以顯著減少引用失效問題,因為智能指針管理的是指向堆上對象的指針,而不是對象本身。
#include <iostream>
#include <memory>
#include <vector>int main() {std::vector<std::shared_ptr<int>> vec = {std::make_shared<int>(1),std::make_shared<int>(2),std::make_shared<int>(3)};std::shared_ptr<int>& ref = vec[1];  // 引用第二個元素std::cout << *ref << std::endl;      // ref仍然有效,輸出2vec.insert(vec.begin(), std::make_shared<int>(0));  // 在開頭插入一個元素std::cout << *ref << std::endl;  return 0;
}

編譯:

Program returned: 139
Program stdout
2
Program stderr
Program terminated with signal: SIGSEGV

二、std::vector中元素引用失效問題

std::vector在以下情況下可能導致引用失效:

  • 重新分配內存:當vector的容量不夠時,會重新分配內存,將現有元素移動到新的內存位置。
  • 插入和刪除:在中間插入或刪除元素時,后續元素會被移動,從而使指向這些元素的引用失效。

避免引用失效的方法:

  • 預先分配足夠的空間:使用reserve方法預先分配足夠的空間,以減少重新分配內存的次數。
std::vector<int> vec;
vec.reserve(100); // 預先分配足夠的空間
  • 避免中間插入和刪除:盡量減少在中間插入和刪除元素的操作,可以選擇在尾部插入或刪除。

三、std::deque中元素引用失效問題

std::deque的設計使其在頭尾插入和刪除操作中引用失效的可能性較低,但在中間插入和刪除時仍然可能導致引用失效。

避免引用失效的方法:

  • 避免中間插入和刪除:和vector類似,盡量減少在中間插入和刪除元素的操作。
  • 使用迭代器:在插入或刪除元素后,重新獲取迭代器。

使用智能指針避免同樣會導致引用失效問題

  • 在隊列中間插入新的元素之后,舊的元素的值不正確
#include <deque>
#include <iostream>
#include <memory>
#include <vector>int main() {std::deque<std::shared_ptr<int>> deq = {std::make_shared<int>(1),std::make_shared<int>(2),std::make_shared<int>(3)};std::shared_ptr<int>& ref = deq[1];  // 引用第二個元素std::cout << *ref << std::endl;      // ref仍然有效,輸出2deq.insert(deq.begin() + 1,std::make_shared<int>(10));  // 在第二個位置插入元素std::cout << *ref << std::endl;  // ref仍然有效,   但是輸出10return 0;
}

編譯:

Program returned: 0
Program stdout
2
10

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

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

相關文章

微信小程序的事件對象屬性,事件綁定

微信小程序 小程序簡介 1 小程序與普通網頁開發的區別&#xff1f; 1運行環境的不同&#xff1a;網頁運行在瀏覽器&#xff0c;小程序運行在微信環境&#xff1b; 2.API 不同&#xff1a;小程序無法調用 DOM 和 BOM 的 API&#xff0c;但可以調用微信環境提供的 API&#xff1…

單工無線發射接收系統

1 緒論 隨著無線電技術的發展,通訊方式也從傳統的有線通訊逐漸轉向無線通訊。由于傳統的有線傳輸系統有配線的問題,較不便利,而無線通訊具有成本廉價、建設工程周期短、適應性好、擴展性好、設備維護容易實現等特點,故未來通訊方式將向無線傳輸系統方向發展。同時,實現系…

mfc140.dll丟失原因和mfc140.dll丟失修復辦法分享

mfc140.dll是與微軟基礎類庫&#xff08;Microsoft Foundation Classes, MFC&#xff09;緊密相關的動態鏈接庫&#xff08;DLL&#xff09;文件。MFC是微軟為C開發者設計的一個應用程序框架&#xff0c;用于簡化Windows應用程序的開發工作。以下是mfc140.dll文件的一些關鍵屬性…

棧的實現(C語言)

文章目錄 前言1.棧的概念及結構2.棧的實現3.具體操作3.1.初始化棧(StackInit)和銷毀棧(StackDestory)3.2.入棧(StackPush)和出棧(StackPop)3.3.獲得棧的個數(StackSize)、獲得棧頂元素(StackTop)以及判空(StackEmpty) 前言 前段時間我們學習過了鏈表和順序表等相關操作&#x…

go-zero 實戰(4)

中間件 在 userapi 項目中引入中間件。go項目中的中間可以處理請求之前和之后的邏輯。 1. 在 userapi/internal目錄先創建 middlewares目錄&#xff0c;并創建 user.go文件 package middlewaresimport ("github.com/zeromicro/go-zero/core/logx""net/http&q…

經濟寒冬下的黃金跳板:方案、活動、競標一手掌握

推薦策劃人必備的寶藏地產策劃資源平臺&#xff0c; 訂閱浩叫&#xff1a;地產營銷策劃圈。這個平臺簡直是地產策劃人的百寶箱&#xff0c;里面藏著無數的策劃秘籍&#xff0c;等著你來挖掘。 這個平臺就像是一個大型的方案庫&#xff0c;里面收錄了眾多知名地產企業的內部資料…

leetcode:計數質數

class Solution { public:// 如果 x 是質數&#xff0c;那么大于 x 的 x 的倍數 2x,3x… 一定不是質數int countPrimes(int n) {vector<int> isPrime(n, 1);int ans 0;for (int i 2; i < n; i) {if (isPrime[i]) {ans 1;if ((long long)i * i < n) {for (int j …

leetcode-55 跳躍游戲

leetcode Problem: 55. 跳躍游戲 思路 假設我們是一個小人&#xff0c;從第一個下標開始&#xff0c;每次經過一個位置&#xff0c;我們就可以根據當前位置的數值nums[i]和位置下標i計算出該位置所能到達的后續位置的最大值rnums[i]i。而這個r之前的區域一定都是可以經過的。…

AI 談“潯川AI翻譯機”

在天工AI&#xff0c;天工AI在全網搜索“潯川AI翻譯機”。 1 創作助手談“潯川AI翻譯機”&#xff1a; “潯川AI翻譯機”是一個利用人工智能技術進行語言翻譯的設備或應用程序。它可以將一種語言的文字或口語翻譯成另一種語言&#xff0c;以實現不同語言之間的溝通和理解。潯…

08. Redis 緩存穿透和雪崩

文章目錄 1. 緩存穿透&#xff08;查不到導致的&#xff09;1.1 概念1.2 解決方案布隆過濾器緩存空對象 2. 緩存擊穿&#xff08;量太大、緩存過期&#xff09;2.1 概念2.2 解決方案設置熱點數據永不過期加互斥鎖 3. 緩存雪崩&#xff08;緩存集體失效或 Redis 宕機&#xff09…

說一下你對dom驅動和數據驅動的理解

DOM驅動和數據驅動是前端開發中兩種常見的操作方式&#xff0c;尤其在構建用戶界面時。下面&#xff0c;我將分別解釋這兩種驅動方式&#xff0c;并提供詳細的代碼示例。 DOM驅動 DOM驅動的核心思想是直接操作DOM元素來更新用戶界面。在早期的Web開發中&#xff0c;這種方式非…

Linux指令初識

ls:顯示當前目錄底下的指定文件或目錄 ls -l更詳細的信息 ls -a顯示當前目錄下的所有文件 命令中的選項可以一次傳遞多個 ,例如&#xff1a;ls -al 命令和選項有必須一個或多個空格 以.開頭的文件&#xff0c;為隱藏文件ls -a可以看到,ls -l看不見 支持命令拼在一起&#…

牛客熱題:滑動窗口的最大值

&#x1f4df;作者主頁&#xff1a;慢熱的陜西人 &#x1f334;專欄鏈接&#xff1a;力扣刷題日記 &#x1f4e3;歡迎各位大佬&#x1f44d;點贊&#x1f525;關注&#x1f693;收藏&#xff0c;&#x1f349;留言 文章目錄 牛客熱題&#xff1a;滑動窗口的最大值題目鏈接方法一…

DNS服務的部署與配置(2)

1、dns的安裝及開啟 dnf install bind.x86_64 -y #安裝 #Berkeley Internet Name Domain (BIND) systemctl enable --now named #啟用dns服務&#xff0c;服務名稱叫named firewall-cmd --permanent --add-servicedns #火墻設置 firewall-cmd --reload …

【手把手搓組件庫】從零開始實現Element Plus--組件開發

從零開始實現Element Plus--組件開發 nvmnvm的作用&#xff1a;nvm的使用方法 需求分析提示詞Kimi 生成產品需求文檔kimi 生成測試用例 初始化 vitest完善 Button 組件1、定義 types.ts2、Button.vue 引入 types.ts3、添加Button樣式點擊事件 添加節流添加 Icon 集成 StoryBook…

C++第十九彈---string模擬實現(下)

?個人主頁&#xff1a; 熬夜學編程的小林 &#x1f497;系列專欄&#xff1a; 【C語言詳解】 【數據結構詳解】【C詳解】 目錄 1、修改操作 2、迭代器操作 3、字符串操作 4、非成員函數重載操作 總結 1、修改操作 1、string& operator (const char* s); //尾部插入…

【Text2SQL 論文】SeaD:使用 Schema-aware 去噪訓練的 end2end 的 Text2SQL

論文&#xff1a;SeaD: End-to-end Text-to-SQL Generation with Schema-aware Denoising ?? NAACL 2022, arXiv:2105.07911 本論文提出 SeaD 模型&#xff0c;使用 schema-aware 的去噪方法來訓練一個 end2end、seq2seq 的 Transformer 模型來實現 Text2SQL。 一、論文速讀…

C++系列-static成員

&#x1f308;個人主頁&#xff1a;羽晨同學 &#x1f4ab;個人格言:“成為自己未來的主人~” 概念 聲明為static的類成員稱為類的靜態成員&#xff0c;用static修飾的成員變量&#xff0c;稱之為靜態成員變量&#xff0c;用static修飾的成員函數&#xff0c;稱之為靜態成…

stm32學習-流水燈

接線 注意&#xff1a;LED燈長一點的引腳是正極。 配置GPIO 1.使用RCC開啟GPIO時鐘 void RCC_AHBPeriphClockCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState); void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState); void RCC_APB1Perip…

Stanford斯坦福 CS 224R: 深度強化學習 (2)

實用深度強化學習實現技術 強化學習(RL)是一種通過智能體與環境交互來學習最優決策的機器學習范式。而深度強化學習(DRL)則將深度學習技術引入RL領域,利用深度神經網絡強大的函數擬合能力來處理高維觀察空間,取得了顯著的成功。本章我們將重點介紹一種經典的DRL算法:Q-Learnin…