欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

關(guān)于C++中vector的兩個(gè)小tips分享

 更新時(shí)間:2019年05月05日 08:29:04   作者:findingsea  
這篇文章主要給大家介紹了關(guān)于C++中vector的兩個(gè)小tips,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用C++具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧

前言

本來這篇文章標(biāo)題我想起成《關(guān)于 vector 的兩個(gè)小坑》,后來想想,其實(shí)也不算是坑,還是自己對(duì)原理性的東西理解的沒做那么透徹。工作中遇到的很多問題,后來歸根到底都是基礎(chǔ)不牢靠。

vector 擴(kuò)容

這個(gè)問題很經(jīng)典了,但還是不小心踩到。有一個(gè)需求是要對(duì)目標(biāo)元素進(jìn)行復(fù)制,而目標(biāo)元素集合是保存在 vector 里面,于是簡(jiǎn)單思考下就有如下代碼(大致含義):

void Duplidate(vector<Element>* element_list, Element* element) {
element_list.push_back(*element);
}

void Process() {
for (auto& package : package_list) {
if (IsNeedDuplicate()) {
Duplicate(element_list, package->element);
}
}
}

看起來好像沒什么問題,就是當(dāng)前的 package 對(duì)象是否滿足復(fù)制的要求,需要的話,就對(duì) package 的成員 origin_element 進(jìn)行復(fù)制。跑 UT 也正常,然后在測(cè)試的時(shí)候就 coredump 了???core 文件就是掛在了復(fù)制的時(shí)候。這里我一開始就沒明白,一個(gè)簡(jiǎn)單的復(fù)制為什么會(huì)有 coredump。

檢查了很久 element 復(fù)制的場(chǎng)景,甚至想要專門寫一個(gè)拷貝構(gòu)造函數(shù)。最后才恍然大悟, origin_element 指針指向的就是 element_list 里面的元素, element_list 是整體流程的數(shù)據(jù)源, packge 對(duì)象是封裝的中間處理對(duì)象。之前的開發(fā)人員為了方便,直接在 package 對(duì)象上保存了原始的 element 指針,而這個(gè)指針指向的是一個(gè) vector 里的元素。而我新加的邏輯會(huì)往原始的 vector 里面再添加元素,那么就有可能導(dǎo)致 vector 擴(kuò)容,而 vector 擴(kuò)容會(huì)導(dǎo)致整體的復(fù)制,從而導(dǎo)致原來指向這些元素的指針都失效了,靠后的 package 對(duì)象再去訪問 origin_element 就產(chǎn)生了 coredump。

當(dāng)然,從設(shè)計(jì)上來說,就不應(yīng)該保存指向 vector 元素的指針,但是這里有太多舊代碼牽涉,這里就不做討論。

vector::erase()

起因是我在代碼里面新增了如下代碼(大致):

void EraseElement(const vector<Element>::iterator& element_iter,
vector<Element>& element_list) {
while (element_iter != element_list.end()) {
element_list.erase(element_iter);
}
}

然后 cr 的同學(xué)提出了一個(gè)疑問是 element_iter 是 const 不可變的,但是在函數(shù)里有擦除了對(duì)應(yīng)的元素,這里會(huì)不會(huì)有問題?雖然 UT 都已經(jīng)跑過了,但是這種寫法的確比較奇怪,于是就借機(jī)學(xué)習(xí)了一下 vector::erase() 的實(shí)現(xiàn)原理跟用法。

erase(iterator) 的實(shí)現(xiàn)原理其實(shí)不會(huì)改變 iterator ,而是把后面的元素一個(gè)個(gè)往前移動(dòng),相當(dāng)于是 iterator 指向的元素本身發(fā)生了變化,所以可以用 const 來修飾這個(gè) iterator 。但是這里用 cosnt & 其實(shí)是沒有錯(cuò)但是無用的修飾,除了容易讓人誤判之外,其實(shí)沒有什么實(shí)際用途。我之前是為了修正 cpplint 才把reference 改成 const reference。

另外 erase 本身的確比較危險(xiǎn),主要還是 erase 的時(shí)候 iterator 本身沒發(fā)生變化,但是指向的元素變了,,在很多時(shí)候 iterator 會(huì)自然地指向下一個(gè)元素,但是由于這是未定義的行為,這里面可能會(huì)有不可預(yù)期的地方,所以最終改成顯示的獲取返回重新賦值( erase() 會(huì)返回下一個(gè)迭代器,但這一點(diǎn)常常被忽略),這樣就能保證安全性了。更安全更推薦的做法應(yīng)該是使用 remove_if() 這里就不展開講了。

void EraseElement(vector<Element>& element_list,
vector<Element>::iterator element_iter ) {
while (element_iter != element_list.end()) {
element_iter = element_list.erase(element_iter);
}
}

總結(jié)

以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)腳本之家的支持。

相關(guān)文章

  • C語言示例講解switch分支語句的用法

    C語言示例講解switch分支語句的用法

    這篇文章主要為大家介紹了switch語句,switch語句是我們常見會(huì)用到的結(jié)構(gòu),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-06-06
  • C語言編程數(shù)據(jù)在內(nèi)存中的存儲(chǔ)詳解

    C語言編程數(shù)據(jù)在內(nèi)存中的存儲(chǔ)詳解

    本篇文章是C語言編程篇,主要為大家介紹C語言編程中數(shù)據(jù)在內(nèi)存中存儲(chǔ)解析,有需要的朋友可以借鑒參考下,希望可以有所幫助
    2021-09-09
  • C語言18個(gè)必背經(jīng)典程序

    C語言18個(gè)必背經(jīng)典程序

    這篇文章主要分下工的是18個(gè)C語言必背的經(jīng)典程序,下面文章我們就來看看實(shí)例,需要的小伙伴可以參考一下喲,希望對(duì)你有所幫助
    2021-10-10
  • C++超詳細(xì)講解稀疏矩陣

    C++超詳細(xì)講解稀疏矩陣

    今天小編就為大家分享一篇關(guān)于C++稀疏矩陣的轉(zhuǎn)置思路并實(shí)現(xiàn)乘法,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2022-05-05
  • set_new_handler(0)有什么用

    set_new_handler(0)有什么用

    本文主要介紹了set_new_handler(0)有什么用,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-08-08
  • C++ com編程學(xué)習(xí)詳解

    C++ com編程學(xué)習(xí)詳解

    這篇文章主要介紹了C++ COM編程的學(xué)習(xí)過程,在C++中,可以使用抽象基類來實(shí)現(xiàn)COM接口,需要的朋友可以參考下,希望能夠給你帶來幫助
    2021-09-09
  • 關(guān)于C++中push_back()函數(shù)的用法及代碼實(shí)例

    關(guān)于C++中push_back()函數(shù)的用法及代碼實(shí)例

    push_back是vector的一個(gè)方法,表示將一個(gè)元素存儲(chǔ)到容器的末尾,下面這篇文章主要給大家介紹了關(guān)于C++中push_back()函數(shù)用法的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-11-11
  • C++?解決求兩個(gè)鏈表的第一個(gè)公共結(jié)點(diǎn)問題

    C++?解決求兩個(gè)鏈表的第一個(gè)公共結(jié)點(diǎn)問題

    本文主要介紹了利用C++實(shí)現(xiàn)輸入兩個(gè)無環(huán)的單向鏈表時(shí),找出它們的第一個(gè)公共結(jié)點(diǎn)的問題。文章中的示例代碼簡(jiǎn)潔易懂,感興趣的同學(xué)可以和小編一起學(xué)習(xí)一下
    2021-12-12
  • c++中nlohmann?json的基本使用教程

    c++中nlohmann?json的基本使用教程

    nlohmann/json 是一個(gè)C++實(shí)現(xiàn)的JSON解析器,使用非常方便直觀,下面這篇文章主要給大家介紹了關(guān)于c++中nlohmann?json基本使用的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-09-09
  • 數(shù)據(jù)結(jié)構(gòu)C語言鏈表的實(shí)現(xiàn)介紹

    數(shù)據(jù)結(jié)構(gòu)C語言鏈表的實(shí)現(xiàn)介紹

    大家好,本篇文章主要講的是數(shù)據(jù)結(jié)構(gòu)C語言鏈表的實(shí)現(xiàn)介紹,感興趣的同學(xué)趕快來看一看吧,對(duì)你有幫助的話記得收藏一下
    2021-12-12

最新評(píng)論