亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

C++ 迭代器失效問題解決

 更新時間:2024年01月23日 15:52:44   作者:Faiz..  
在C++中,當一個vector進行了插入或刪除操作時,其迭代器可能會失效,本文就來介紹一下C++ 迭代器失效問題解決,具有一定的參考價值,感興趣的可以了解一下

1.vector迭代器失效問題

迭代器的主要作用就是讓算法能夠不用關心底層數據結構,其底層實際就是一個指針,或者是對指針進行了封裝 ,比如: vector 的迭代器就是原生態(tài)指針 T* 。因此 迭代器失效,實際就是迭代器底層對應指針所指向的 空間被銷毀了,而使用一塊已經被釋放的空間 ,造成的后果是程序崩潰 ( 即 如果繼續(xù)使用已經失效的迭代器, 程序可能會崩潰 ) 。

在C++中,當一個vector進行了插入或刪除操作時,其迭代器可能會失效。這是因為在插入或刪除操作之后,vector可能會重新分配內存空間,導致原來的迭代器指向的位置不再有效。

可能會導致其迭代器失效的操作有

1.底層空間改變

1. 會引起其底層空間改變的操作,都有可能是迭代器失效 ,比如: resize 、 reserve 、 insert 、 assign 、push_back等。

#define  _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
#include<vector>

int main()
{
	vector<int> v;
	v = { 1,2,3,4,5,6 };
	auto it = v.begin();
	//使用reserve擴容,可能會引起底層容量的改變,舊空間釋放,但是it依舊使用的時釋放前的舊空間
	v.reserve(100);
	while (it != v.end())
	{
		cout << *it << " ";
		++it;
	}

	return 0;
}

我們使用resize 、 reserve 、 insert 、 assign、 push_back等操作都可能會導致擴容, 也就是說vector底層原理舊空間被釋放掉, 而在打印時,it還使用的是釋放之間的舊空間,在對it迭代器操作時,實際操作的是一塊已經被釋放的 空間,而引起代碼運行時崩潰。

如果我們在擴容后重新賦值即可解決這個問題,可以繼續(xù)操作it迭代器。

2.指定位置元素的刪除操作

#define  _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
#include<vector>

int main()
{
	vector<int> v;
	v = { 1,2,3,4,5,6 };
	//auto it = v.begin();
	//使用reserve擴容,可能會引起底層容量的改變,舊空間釋放,但是it依舊使用的時釋放前的舊空間
	//v.reserve(100);
	auto it = v.begin();
	while (it != v.end())
	{
		v.erase(it);  //刪除it位置的數據,導致迭代器失效
		//這時再對it進行操作就是非法訪問
		cout << *it << endl;
		++it;
	}

	return 0;
}

如圖中代碼,運行會崩潰

erase 刪除 pos 位置元素后, pos 位置之后的元素會往前搬移,沒有導致底層空間的改變,理論上講迭代器不應該會失效,但是:如果pos 剛好是最后一個元素,刪完之后 pos 剛好是 end 的位置,而 end 位置是沒有元素的,那么pos 就失效了。因此刪除 vector 中任意位置上元素時, vs 就認為該位置迭代器失效了。

如果在刪除后對迭代器it重新賦值,這個時候就不會失效,因為erase返回刪除元素下一個位置元素的迭代器。

2.Linux下的迭代器失效檢測

Linux 下, g++ 編譯器對迭代器失效的檢測并不是非常嚴格,處理也沒有 vs 下極端。

1.擴容

運行如下代碼:

可以運行但是結果已經出錯。

2.刪除

運行如下代碼

可以正常運行,erase刪除任意位置代碼后,linux下迭代器并沒有失效 因為空間還是原來的空間,后序元素往前搬移了,it的位置還是有效的

但是如果刪除的是最后一個元素呢

程序崩潰,因為刪除最后一個元素,刪除后it已經超過end,++it導致程序崩潰

3.解決方法

與 vector 類似, string 在插入 + 擴容操作 +erase 之后,迭代器也會失效

迭代器失效解決辦法:在使用前,對迭代器重新賦值即可

1.在進行插入或刪除操作之后,更新迭代器的位置,使其指向有效的元素。

2.在進行插入或刪除操作之前,先將迭代器保存下來,然后再進行操作之后重新定位迭代器。

3.另外,C++11引入了emplace_back()和emplace()函數,它們可以在vector中直接構造對象,而不是先創(chuàng)建臨時對象再插入,這樣可以減少迭代器失效的可能性 

到此這篇關于C++ 迭代器失效問題解決的文章就介紹到這了,更多相關C++ 迭代器失效內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • C語言實現二叉樹遍歷的迭代算法

    C語言實現二叉樹遍歷的迭代算法

    這篇文章主要介紹了C語言實現二叉樹遍歷的迭代算法,包括二叉樹的中序遍歷、先序遍歷及后序遍歷等,是非常經典的算法,需要的朋友可以參考下
    2014-09-09
  • 關于win32 gettimeofday替代方案

    關于win32 gettimeofday替代方案

    下面小編就為大家?guī)硪黄P于win32 gettimeofday替代方案。小編覺得挺不錯的,現在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-12-12
  • 如何給隨機數加密

    如何給隨機數加密

    隨機數加密的簡單算法,需要的朋友可以參考一下
    2013-03-03
  • C++類繼承 繼承后函數的值實現詳解

    C++類繼承 繼承后函數的值實現詳解

    這篇文章主要介紹了C++類繼承 繼承后函數的值實現詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-09-09
  • C++構造函數詳解

    C++構造函數詳解

    這篇文章主要介紹了C++構造函數詳解,上一篇文章我們介紹了定義了類,在使用之前,往往還需要對類進行初始化。這篇介紹的就是對類進行初始化的方法,需要的朋友可以參考一下
    2022-01-01
  • C++17新特性個人總結

    C++17新特性個人總結

    這篇文章主要介紹了C++17新特性個人總結,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-07-07
  • C++中Pimpl的慣用法詳解

    C++中Pimpl的慣用法詳解

    Pimpl(Pointer?to?Implementation)是一種常見的?C++?設計模式,用于隱藏類的實現細節(jié),本文將通過一個較為復雜的例子,展示如何使用智能指針來實現?Pimpl?慣用法,需要的可以參考下
    2023-09-09
  • 帶你了解C++中vector的用法

    帶你了解C++中vector的用法

    大家好,本篇文章主要講的是帶你了解C++中vector的用法,感興趣的同學趕快來看一看吧,對你有幫助的話記得收藏一下
    2022-01-01
  • java 中ArrayList與LinkedList性能比較

    java 中ArrayList與LinkedList性能比較

    這篇文章主要介紹了java 中ArrayList與LinkedList性能比較的相關資料,需要的朋友可以參考下
    2017-03-03
  • c++友元函數與友元類的深入解析

    c++友元函數與友元類的深入解析

    友元函數的特點是能夠訪問類中的私有成員的非成員函數。友元函數從語法上看,它與普通函數一樣,即在定義上和調用上與普通函數一樣
    2013-07-07

最新評論